Czy w C / C ++ zmienne globalne są tak złe, jak myśli mój profesor?
Czy w C / C ++ zmienne globalne są tak złe, jak myśli mój profesor?
Odpowiedzi:
Problem ze zmiennymi globalnymi polega na tym, że ponieważ każda funkcja ma do nich dostęp, coraz trudniej jest ustalić, które funkcje faktycznie odczytują i zapisują te zmienne.
Aby zrozumieć, jak działa aplikacja, musisz wziąć pod uwagę każdą funkcję, która modyfikuje stan globalny. Można to zrobić, ale wraz z rozwojem aplikacji będzie ona trudniejsza do tego stopnia, że będzie praktycznie niemożliwa (lub przynajmniej kompletna strata czasu).
Jeśli nie korzystasz ze zmiennych globalnych, możesz przekazać stan pomiędzy różnymi funkcjami w razie potrzeby. W ten sposób masz znacznie większą szansę na zrozumienie, co robi każda funkcja, ponieważ nie musisz brać pod uwagę stanu globalnego.
Ważne jest, aby pamiętać o ogólnym celu: przejrzystości
Istnieje reguła „bez zmiennych globalnych”, ponieważ przez większość czasu zmienne globalne sprawiają, że znaczenie kodu jest mniej jasne.
Jednak, podobnie jak wiele reguł, ludzie pamiętają tę regułę, a nie jej przeznaczenie.
Widziałem programy, które wydają się podwoić rozmiar kodu, przekazując ogromną liczbę parametrów, aby uniknąć zła zmiennych globalnych. W końcu użycie globałów uczyniłoby program bardziej zrozumiałym dla osób go czytających. Bezmyślnie przestrzegając słowa reguły, oryginalny programista zawiódł zamiar reguły.
Tak, globały są często złe. Ale jeśli uważasz, że w końcu intencja programisty została wyjaśniona dzięki zastosowaniu zmiennych globalnych, to idź dalej. Pamiętaj jednak o spadku przejrzystości, który pojawia się automatycznie, gdy zmusisz kogoś do uzyskania dostępu do drugiego fragmentu kodu (globali), aby zrozumieć, jak działa ten pierwszy fragment.
Mój profesor zwykł mówić coś w stylu: używanie zmiennych globalnych jest w porządku, jeśli używasz ich poprawnie. Nie sądzę, żebym kiedykolwiek dobrze je używał, więc rzadko ich używałem.
static
zmiennych globalnych, językiem jest C. Ponieważ są ograniczone do stosunkowo małych jednostek tłumaczeniowych, zaczynają przypominać zmienne klasowe obiektów C ++.
program lifetime, file scope variables
. I stają się dość globalne, gdy przekażesz wskaźnik do zmiennej światu zewnętrznemu (co jest niemożliwe w przypadku zmiennych automatycznych).
static
zmienne globalne mają ograniczony zakres do tej samej jednostki tłumaczeniowej. Ale mają żywotność do końca programu jako dowolną zmienną globalną.
Zmiennych globalnych należy używać tylko wtedy, gdy nie ma alternatywy. I tak, obejmuje Singletony. W 90% przypadków zmienne globalne są wprowadzane w celu zaoszczędzenia kosztów związanych z pomijaniem parametru. A potem dzieje się wielowątkowość / testowanie jednostkowe / kodowanie konserwacyjne i masz problem.
Tak, w 90% przypadków zmienne globalne są złe. Wyjątki prawdopodobnie nie będą widoczne w latach studiów. Jedyny wyjątek, który mogę oderwać od głowy, dotyczy z natury globalnych obiektów, takich jak tabele przerwań. Rzeczy takie jak połączenie DB wydają się być globalne, ale nie są.
Problem, który tworzą zmienne globalne dla programisty, polega na tym, że rozszerza on powierzchnię sprzęgania między komponentami między różnymi komponentami używającymi zmiennych globalnych. Oznacza to, że wraz ze wzrostem liczby składników wykorzystujących zmienną globalną może również wzrosnąć złożoność interakcji. To zwiększone sprzężenie zwykle ułatwia wprowadzanie defektów do systemu podczas wprowadzania zmian, a także utrudnia diagnozowanie i poprawianie defektów. To zwiększenie sprzężenia może również zmniejszyć liczbę dostępnych opcji podczas wprowadzania zmian i może zwiększyć wysiłek wymagany do wprowadzenia zmian, ponieważ często należy prześledzić różne moduły, które również używają zmiennej globalnej w celu ustalenia konsekwencji zmian.
Celem enkapsulacji , która jest w zasadzie przeciwieństwem stosowania zmiennych globalnych, jest zmniejszenie sprzężenia, aby łatwiej i bezpieczniej zrozumieć i zmienić źródło. Testy jednostkowe są znacznie łatwiejsze, gdy nie są używane zmienne globalne.
Na przykład jeśli masz prostą globalną zmienną całkowitą, która jest używana jako wyliczony wskaźnik, który różne komponenty wykorzystują jako maszynę stanu, a następnie dokonujesz zmiany poprzez dodanie nowego stanu dla nowego komponentu, musisz prześledzić wszystkie pozostałe składniki, aby zapewnić, że zmiana nie wpłynie na nie. Przykładem potencjalnego problemu może być użycie switch
instrukcji do testowania wartości zmiennej globalnej wyliczenia z case
instrukcjami dla każdej z bieżących wartości w różnych miejscach i zdarza się, że niektóre switch
instrukcje nie mają default
przypadku do obsłużenia nieoczekiwana wartość dla globalnego nagle masz niezdefiniowane zachowanie w odniesieniu do aplikacji.
Z drugiej strony użycie współdzielonego obszaru danych może być wykorzystane do przechowywania zestawu parametrów globalnych, do których odwołuje się aplikacja. Takie podejście jest często stosowane w aplikacjach osadzonych z małą ilością pamięci.
Podczas korzystania ze zmiennych globalnych w tego rodzaju aplikacjach zazwyczaj odpowiedzialność za zapis w obszarze danych jest przypisana do pojedynczego komponentu, a wszystkie pozostałe komponenty widzą ten obszar jako const
i odczytują go, nigdy do niego nie pisząc. Takie podejście ogranicza problemy, które mogą się rozwinąć.
Kilka problemów ze zmiennymi globalnymi, które należy rozwiązać
Gdy źródło zmiennej globalnej, takiej jak struct, zostanie zmodyfikowane, wszystko, co go używa, musi zostać ponownie skompilowane, aby wszystko, co korzysta ze zmiennej, znało jej prawdziwy rozmiar i szablon pamięci.
Jeśli więcej niż jeden składnik może modyfikować zmienną globalną, możesz napotkać problemy z niespójnością danych znajdujących się w zmiennej globalnej. W przypadku aplikacji wielowątkowej prawdopodobnie będziesz musiał dodać jakiś region blokujący lub krytyczny, aby zapewnić sposób, że tylko jeden wątek może modyfikować zmienną globalną na raz, a gdy wątek modyfikuje zmienną, wszystkie zmiany są zakończone i zatwierdzone, zanim inne wątki będą mogły zapytać o zmienną lub ją zmodyfikować.
Debugowanie aplikacji wielowątkowej, która korzysta ze zmiennej globalnej, może być trudniejsze. Możesz spotkać się z warunkami wyścigu, które mogą powodować wady, które są trudne do odtworzenia. Z kilkoma komponentami komunikującymi się za pośrednictwem zmiennej globalnej, szczególnie w aplikacji wielowątkowej, wiedza o tym, który komponent zmienia zmienną, kiedy i jak ją zmienia, może być bardzo trudna do zrozumienia.
Zderzenie nazw może być problemem przy stosowaniu zmiennych globalnych. Zmienna lokalna o takiej samej nazwie jak zmienna globalna może ukryć zmienną globalną. Podczas korzystania z języka programowania C można również natknąć się na problem konwencji nazewnictwa. Obejściem tego problemu jest podzielenie systemu na podsystemy ze zmiennymi globalnymi dla konkretnego podsystemu, zaczynając od tych samych pierwszych trzech liter (zobacz to na temat rozwiązywania kolizji przestrzeni nazw w celu C ). C ++ zapewnia przestrzenie nazw, a za pomocą C można obejść ten problem, tworząc globalnie widoczną strukturę, której członkami są różne elementy danych i wskaźniki do danych i funkcji, które są dostarczane w pliku jako statyczne, a więc z widocznością pliku, dzięki czemu można się do nich odwoływać tylko poprzez globalnie widoczna struktura.
W niektórych przypadkach pierwotne zamiary aplikacji są zmieniane, tak że zmienne globalne określające stan pojedynczego wątku są modyfikowane, aby umożliwić działanie kilku duplikatów wątków. Przykładem może być prosta aplikacja przeznaczona dla pojedynczego użytkownika korzystająca ze zmiennych globalnych dla stanu, a następnie zarząd przychodzi z prośbą o dodanie interfejsu REST, aby umożliwić zdalnym aplikacjom działanie jako użytkownicy wirtualni. Więc teraz musisz zduplikować zmienne globalne i ich informacje o stanie, aby pojedynczy użytkownik, a także każdy użytkownik wirtualny ze zdalnych aplikacji, mieli swój własny, unikalny zestaw zmiennych globalnych.
Korzystanie z C ++ namespace
i struct
techniki dla C.
Dla języka programowania C ++ namespace
dyrektywa stanowi ogromną pomoc w zmniejszeniu szansy na konflikt nazw. namespace
wraz z class
różnymi słowami kluczowymi dostępu ( private
, protected
i public
) zapewniają większość narzędzi potrzebnych do enkapsulacji zmiennych. Jednak język programowania C nie zapewnia tej dyrektywy. To księgowanie przepełnienia stosu , Przestrzenie nazw w C , zapewnia pewne techniki dla C.
Przydatną techniką jest posiadanie pojedynczego obszaru danych rezydującego w pamięci, który jest zdefiniowany jako taki, struct
który ma globalną widoczność i w tym struct
są wskaźniki różnych zmiennych globalnych i funkcji, które są ujawniane. Rzeczywiste definicje zmiennych globalnych podano w zakresie pliku za pomocą static
słowa kluczowego. Jeśli następnie użyjesz tego const
słowa kluczowego, aby wskazać, które są tylko do odczytu, kompilator może pomóc Ci wymusić dostęp tylko do odczytu.
Korzystanie z tej struct
techniki może również obejmować globalność, dzięki czemu staje się ona rodzajem pakietu lub komponentu, który okazuje się globalny. Dzięki temu komponentowi łatwiej jest zarządzać zmianami, które wpływają na globalność i funkcjonalność za pomocą globalnej.
Jednak podczas namespace
lub struct
technika może pomóc zarządzać nazwy starć, podstawowe problemy sprzężenia między składnika których stosowanie globalnych wprowadza w szczególności w nowoczesnych aplikacji wielowątkowym nadal istnieją.
Tak, ale nie ponosisz kosztu zmiennych globalnych, dopóki nie przestaniesz pracować w kodzie, który używa zmiennych globalnych i nie zaczniesz pisać czegoś innego, który używa kodu, który używa zmiennych globalnych. Ale koszty wciąż tam są.
Innymi słowy, jest to długoterminowy koszt pośredni i jako taki większość ludzi uważa, że nie jest źle.
Jeśli to możliwe, twój kod zostanie poddany intensywnej analizie podczas procesu w Sądzie Najwyższym , to musisz unikać zmiennych globalnych.
Zobacz ten artykuł: Kod alkomatu Buggy odzwierciedla znaczenie przeglądu źródła
Wystąpiły pewne problemy ze stylem kodu, które zostały zidentyfikowane w obu badaniach. Jednym z problemów stylistycznych, które dotyczyły recenzentów, było szerokie stosowanie niezabezpieczonych zmiennych globalnych . Jest to uważane za kiepską formę, ponieważ zwiększa ryzyko, że stan programu stanie się niespójny lub że wartości zostaną przypadkowo zmodyfikowane lub nadpisane. Badacze wyrazili również pewne obawy dotyczące faktu, że precyzja dziesiętna nie jest utrzymywana konsekwentnie w całym kodzie.
Założę się, że ci programiści żałują, że nie użyli zmiennych globalnych!
Zmienne globalne są tak złe, jak je tworzysz, nie mniej.
Jeśli tworzysz w pełni zamknięty program, możesz używać globałów. Używanie globałów jest „grzechem”, ale grzechy programowania są mało filozoficzne.
Jeśli sprawdzisz L.in.oleum , zobaczysz język, którego zmienne są wyłącznie globalne. Jest to nieskalowalne, ponieważ wszystkie biblioteki nie mają innego wyboru, jak używać globałów.
To powiedziawszy, jeśli masz wybór i możesz zignorować filozofię programisty, globale nie są wcale takie złe.
Nie są też Gotos, jeśli dobrze je wykorzystasz.
Dużym „złym” problemem jest to, że jeśli użyjesz ich źle, ludzie krzyczą, lądownik marsjański rozbije się, a świat wysadzi… lub coś w tym rodzaju.
Odpowiedziałbym na to pytanie innym pytaniem: Czy używasz pojedynczych przycisków / Czy pojedyncze przyciski są złe?
Ponieważ (prawie wszystkie) użycie singeltonów jest uwielbioną zmienną globalną.
Problemem jest to, że są złe , a bardziej, że są niebezpieczne . Mają własny zestaw zalet i wad, a są sytuacje, w których są albo najbardziej wydajni, albo jedyny sposób na osiągnięcie określonego zadania. Jednak są bardzo łatwe do niewłaściwego użycia, nawet jeśli podejmiesz kroki, aby zawsze używać ich prawidłowo.
Kilka zalet:
Kilka wad:
Zauważ, że jeśli chcesz, pierwsze dwa plusy i dwa pierwsze minusy, które wymieniłem, są dokładnie takie same, tylko z innym brzmieniem. Jest tak, ponieważ cechy zmiennej globalnej mogą być rzeczywiście przydatne, ale same cechy, które czynią je użytecznymi, są źródłem wszystkich ich problemów.
Kilka potencjalnych rozwiązań niektórych problemów:
Globals
lub GlobalVars
) lub użyj standardowej konwencji nazewnictwa dla zmiennych globalnych (takich jak global_[name]
lub g_module_varNameStyle
(jak wspomniano w underscore_d w komentarzach )). Spowoduje to zarówno udokumentowanie ich użycia (można znaleźć kod, który korzysta ze zmiennych globalnych, wyszukując przestrzeń nazw / nazwę struktury), jak i zminimalizować wpływ na globalną przestrzeń nazw.extern
w powiązanym nagłówku, aby ich użycie mogło być ograniczone do jednostek kompilacji, które potrzebują do nich dostępu. Jeśli Twój kod opiera się na wielu zmiennych globalnych, ale każda jednostka kompilacji potrzebuje tylko dostępu do kilku z nich, możesz rozważyć posortowanie ich w wielu plikach źródłowych, dzięki czemu łatwiej jest ograniczyć dostęp każdego pliku do zmiennych globalnych.To, czy są dobre, czy złe, zależy od tego, jak z nich korzystasz. Większość z nich źle je wykorzystuje, stąd ogólna ostrożność wobec nich. Przy właściwym stosowaniu mogą być dużym dobrodziejstwem; jeśli źle wykorzystane, jednak mogą i będą wracać gryźć jak i kiedy najmniej się tego spodziewasz.
Dobrym sposobem na to jest to, że sami nie są źli, ale umożliwiają zły projekt i mogą wykładniczo zwielokrotniać skutki złego projektu.
Nawet jeśli nie zamierzasz ich używać, lepiej wiedzieć, jak ich używać bezpiecznie i zdecydować, że nie, niż nie używać ich, ponieważ nie wiesz, jak bezpiecznie z nich korzystać. Jeśli kiedykolwiek znajdziesz się w sytuacji, w której musisz zachować wcześniej istniejący kod, który opiera się na zmiennych globalnych, możesz mieć trudności, jeśli nie wiesz, jak prawidłowo z nich korzystać.
g_module_varNameStyle
doskonale czytelne. Żeby było jasne, nie używam globalnych, czy mogę go łatwo uniknąć - słowo kluczowe łatwo , bo odkąd przestał muszą być unikane wierzyć - albo raczej ukrywane - za wszelką cenę, mam o wiele lepszy czas, i mój kod jest (szokujący!) zdecydowanie bardziej uporządkowany
Jak ktoś powiedział (parafrazuję) w innym wątku: „Takie zasady nie powinny być łamane, dopóki nie w pełni zrozumiesz konsekwencje takiego postępowania”.
Są chwile, kiedy zmienne globalne są potrzebne lub przynajmniej bardzo pomocne (na przykład praca z oddzwanianiami zdefiniowanymi przez system). Z drugiej strony są one również bardzo niebezpieczne z wszystkich powodów, o których ci mówiono.
Istnieje wiele aspektów programowania, które prawdopodobnie należy pozostawić ekspertom. Czasami POTRZEBUJESZ bardzo ostrego noża. Ale nie możesz użyć jednego, dopóki nie będziesz gotowy ...
Zmienne globalne są ogólnie złe, szczególnie jeśli inne osoby pracują nad tym samym kodem i nie chcą spędzać 20 minut na szukaniu wszystkich miejsc, do których odwołuje się zmienna. Dodanie wątków, które modyfikują zmienne, wprowadza zupełnie nowy poziom problemów.
Stałe globalne w anonimowej przestrzeni nazw używanej w pojedynczej jednostce tłumaczeniowej są dobre i wszechobecne w profesjonalnych aplikacjach i bibliotekach. Ale jeśli dane są zmienne i / lub muszą być współużytkowane przez wiele JT, możesz je kapsułkować - jeśli nie ze względu na projekt, to ze względu na osobę debugującą lub pracującą z twoim kodem.
Używanie zmiennych globalnych przypomina trochę zamiatanie ziemi pod dywan. Jest to szybka naprawa i znacznie łatwiejsze w krótkim okresie niż uzyskanie pojemnika na kurz lub odkurzacza, aby go wyczyścić. Jeśli jednak później przesuniesz dywan, będziesz miał pod spodem wielki bałagan.
Myślę, że twój profesor próbuje powstrzymać zły nawyk, zanim jeszcze się zacznie.
Zmienne globalne mają swoje miejsce i jak wiele osób mówi, wiedząc, gdzie i kiedy ich używać, może być skomplikowane. Myślę więc, że zamiast wdawać się w sedno tego, dlaczego, jak, kiedy i gdzie zmiennych globalnych, profesor postanowił po prostu zakazać. Kto wie, może ich zakazać w przyszłości.
Absolutnie nie. Nadużywanie ich ... to źle.
Bezmyślne usuwanie ich ze względu na to jest ... bezmyślne. O ile nie znasz zalet i wad, najlepiej kieruj się jasno i postępuj zgodnie z tym, czego się nauczyłeś, ale nie ma nic pośredniego w przypadku zmiennych globalnych. Kiedy zrozumiesz zalety i wady, lepiej podejmij własną decyzję.
Zmienne globalne są dobre w małych programach, ale okropne, jeśli są używane w ten sam sposób w dużych programach.
Oznacza to, że możesz łatwo przyzwyczaić się do korzystania z nich podczas nauki. Przed tym twój profesor stara się cię chronić.
Kiedy będziesz bardziej doświadczony, łatwiej będzie nauczyć się, kiedy będą w porządku.
Nie, wcale nie są złe. Musisz przyjrzeć się kodowi (maszynowemu) wygenerowanemu przez kompilator, aby dokonać tego ustalenia, czasami znacznie gorsze jest użycie lokalnego niż globalnego. Zauważ też, że nałożenie zmiennej „statycznej” na zmienną lokalną zasadniczo czyni ją globalną (i stwarza inne brzydkie problemy, które rozwiązałby prawdziwy globalny). „lokalne globale” są szczególnie złe.
Globals daje również czystą kontrolę nad zużyciem pamięci, co jest znacznie trudniejsze w przypadku mieszkańców. Obecnie ma to znaczenie tylko w środowiskach osadzonych, w których pamięć jest dość ograniczona. Przed założeniem, że osadzony jest taki sam jak w innych środowiskach i założeniem, że zasady programowania są takie same we wszystkich obszarach, należy wiedzieć.
Dobrze, że kwestionujesz nauczane zasady, większość z nich nie jest z powodów, o których ci mówiono. Najważniejsza lekcja nie polega jednak na tym, że jest to zasada, którą należy nosić ze sobą na zawsze, ale jest to zasada wymagana, aby honorować, aby przejść tę klasę i iść naprzód. W życiu przekonasz się, że dla firmy XYZ będziesz mieć inne zasady programowania, które w końcu będziesz musiał uszanować, aby nadal otrzymywać wypłatę. W obu sytuacjach możesz podważyć zasadę, ale myślę, że będziesz miał dużo więcej szczęścia w pracy niż w szkole. Jesteś tylko jednym z wielu studentów, twoje miejsce zostanie wkrótce zastąpione, profesorowie tego nie zrobią, w pracy jesteś jednym z małego zespołu graczy, którzy muszą zobaczyć ten produkt do końca i w takim środowisku opracowane zasady dotyczą korzyści członków zespołu, a także produktu i firmy, więc jeśli wszyscy są podobnie nastawieni lub jeśli chodzi o konkretny produkt, istnieje dobry powód techniczny, aby naruszyć coś, czego nauczyłeś się na studiach lub książkę o programowaniu ogólnym, to sprzedaj swój pomysł zespołowi i zapisz go jako prawidłową, jeśli nie preferowaną metodę . W prawdziwym świecie wszystko jest uczciwe.
Jeśli będziesz przestrzegać wszystkich zasad programowania, których nauczyłeś się w szkole lub w książkach, twoja kariera programistyczna będzie bardzo ograniczona. Prawdopodobnie możesz przetrwać i mieć owocną karierę, ale szerokość i szerokość dostępnych dla ciebie środowisk będzie bardzo ograniczona. Jeśli wiesz, jak i dlaczego istnieje reguła i możesz ją obronić, to dobrze, jeśli tylko rozumujesz, ponieważ „tak powiedział mój nauczyciel”, to nie jest tak dobrze.
Zwróć uwagę, że takie tematy są często dyskutowane w miejscu pracy i tak będzie, ponieważ kompilatory i procesory (i języki) ewoluują, zmieniają się także takie zasady i bez obrony twojego stanowiska i być może nauczony przez kogoś z inną opinią, której nie chcesz pójść naprzód.
W międzyczasie, po prostu rób wszystko, co mówi najgłośniej lub mówi największy kij (do czasu, gdy będziesz krzyczał najgłośniej i niesie największy kij).
Chciałbym sprzeciwić się temu, aby w całym tym wątku było poruszone twierdzenie, że sprawia ono, że wielowątkowanie jest trudniejsze lub niemożliwe jako takie. Zmienne globalne są stanem wspólnym, ale alternatywy dla globałów (np. Przekazywanie wskaźników) mogą również współdzielić stan. Problem z wielowątkowością polega na tym, jak prawidłowo używać stanu współdzielonego, a nie czy stan ten jest współdzielony przez zmienną globalną, czy coś innego.
W większości przypadków, gdy robisz wielowątkowość, musisz coś udostępnić. Na przykład we wzorcu producent-konsument możesz udostępniać pewną bezpieczną dla wątków kolejkę, która zawiera jednostki robocze. Możesz je udostępniać, ponieważ ta struktura danych jest bezpieczna dla wątków. To, czy kolejka jest globalna, czy nie, jest całkowicie nieistotne, jeśli chodzi o bezpieczeństwo wątków.
Niejasna nadzieja wyrażona w tym wątku, że przekształcenie programu z jednowątkowego na wielowątkowy będzie łatwiejsza, gdy nie będzie używany globali, jest naiwna. Tak, globale ułatwiają strzelanie sobie w stopę, ale istnieje wiele sposobów na strzelanie sobie.
Nie opowiadam się za globalsami, ponieważ inne punkty nadal są ważne, mam na myśli tylko to, że liczba wątków w programie nie ma nic wspólnego ze zmiennym zakresem.
Tak, ponieważ jeśli pozwolisz, aby niekompetentni programiści z nich korzystali (czytaj 90%, szczególnie naukowcy), uzyskasz ponad 600 globalnych zmiennych rozłożonych na ponad 20 plików i projekt obejmujący 12 000 linii, w których 80% funkcji unieważnia, zwraca nieważność i działa całkowicie w stanie globalnym.
Szybko staje się niemożliwe do zrozumienia, co się dzieje w jednym punkcie, chyba że znasz cały projekt.
Zastosowanie zmiennych globalnych faktycznie zależy od wymagań. Jego zaletą jest to, że zmniejsza obciążenie związane z wielokrotnym przekazywaniem wartości.
Ale twój profesor ma rację, ponieważ rodzi to problemy z bezpieczeństwem, dlatego należy w jak największym stopniu unikać używania zmiennych globalnych. Zmienne globalne powodują również problemy, które czasami są trudne do debugowania .
Na przykład:-
Sytuacje, w których wartości zmiennych są modyfikowane w czasie wykonywania . W tej chwili trudno jest określić, która część kodu go modyfikuje i na jakich warunkach.
Globalne są dobre, jeśli chodzi o konfigurację . Kiedy chcemy, aby nasza konfiguracja / zmiany miały globalny wpływ na cały projekt .
Możemy więc zmienić jedną konfigurację, a zmiany są kierowane do całego projektu . Ale muszę ostrzec, że musisz być bardzo mądry, aby korzystać z globałów.
Wcześniej czy później będziesz musiał zmienić sposób ustawiania tej zmiennej lub co się stanie, gdy będzie ona dostępna, lub po prostu poluj tam, gdzie została zmieniona.
Praktycznie zawsze lepiej jest nie mieć zmiennych globalnych. Po prostu napisz tama, pobierz i ustaw metody i dławik, gdy będziesz ich potrzebować dzień, tydzień lub miesiąc później.
Zwykle używam globałów dla wartości, które rzadko są zmieniane, takie jak singletony lub wskaźniki funkcji, do funkcji w dynamicznie ładowanej bibliotece. Używanie zmiennych globalnych w aplikacjach wielowątkowych prowadzi zwykle do trudnego do śledzenia błędu, więc staram się tego unikać z reguły.
Używanie globalnego zamiast przekazywania argumentu jest często szybsze, ale jeśli piszesz aplikację wielowątkową, co często robisz w dzisiejszych czasach, zazwyczaj nie działa ona zbyt dobrze (możesz użyć statystyki wątków, ale wtedy wzrost wydajności jest wątpliwy) .
W aplikacjach internetowych w ramach Enterprize można używać do przechowywania danych specyficznych dla sesji / okna / wątku / użytkownika na serwerze w celu optymalizacji i do ochrony przed utratą pracy, gdy połączenie jest niestabilne. Jak wspomniano, warunki wyścigu muszą być spełnione. Używamy pojedynczej instancji klasy dla tych informacji i jest ona starannie zarządzana.
Ostatecznie Twój program lub aplikacja może nadal działać, ale musisz być uporządkowany i mieć pełne zrozumienie tego, co się dzieje. Jeśli podzielisz wartość zmiennej między wszystkie funkcje, może być trudno prześledzić, która funkcja zmienia wartość (jeśli funkcja to robi) i sprawia, że debugowanie jest milion razy trudniejsze
bezpieczeństwo jest mniej oznacza, że każdy może manipulować zmiennymi, jeśli są zadeklarowane jako globalne, aby wyjaśnić ten przykład, weź ten przykład, jeśli masz równowagę jako zmienną globalną w swoim programie bankowym, funkcja użytkownika może nią manipulować, podobnie jak urzędnik bankowy może również manipulować to jest problem. tylko użytkownik powinien mieć funkcję tylko do odczytu i wypłacania, ale urzędnik banku może dodać kwotę, gdy użytkownik osobiście przekazuje gotówkę na biurku. tak to działa
W aplikacji wielowątkowej używaj zmiennych lokalnych zamiast zmiennych globalnych, aby uniknąć warunków wyścigu.
Warunek wyścigu występuje, gdy wiele wątków uzyskuje dostęp do współdzielonego zasobu, przy czym co najmniej jeden wątek ma dostęp do zapisu do danych. Następnie wynik programu nie jest przewidywalny i zależy od kolejności dostępu do danych przez różne wątki.
Więcej na ten temat tutaj, https://software.intel.com/en-us/articles/use-intel-parallel-inspector-to-find-race-conditions-in-openmp-based-multithreaded-code