Sind globale Variablen in C / C ++ so schlecht, wie mein Professor glaubt?
Sind globale Variablen in C / C ++ so schlecht, wie mein Professor glaubt?
Antworten:
Das Problem bei globalen Variablen besteht darin, dass es zunehmend schwieriger wird, herauszufinden, welche Funktionen diese Variablen tatsächlich lesen und schreiben, da jede Funktion Zugriff auf diese hat.
Um zu verstehen, wie die Anwendung funktioniert, müssen Sie so ziemlich jede Funktion berücksichtigen, die den globalen Status ändert. Das kann getan werden, aber wenn die Anwendung wächst, wird es schwieriger, praktisch unmöglich zu werden (oder zumindest eine völlige Zeitverschwendung).
Wenn Sie sich nicht auf globale Variablen verlassen, können Sie den Status nach Bedarf zwischen verschiedenen Funktionen weitergeben. Auf diese Weise haben Sie eine viel bessere Chance zu verstehen, was jede Funktion tut, da Sie den globalen Zustand nicht berücksichtigen müssen.
Wichtig ist, sich an das Gesamtziel zu erinnern: Klarheit
Die Regel "Keine globalen Variablen" ist vorhanden, da globale Variablen die Bedeutung von Code meistens weniger klar machen.
Wie bei vielen Regeln erinnern sich die Menschen jedoch an die Regel und nicht daran, was die Regel tun sollte.
Ich habe Programme gesehen, die die Größe des Codes zu verdoppeln scheinen, indem sie eine enorme Anzahl von Parametern herumgereicht haben, um das Übel globaler Variablen zu vermeiden. Am Ende hätte die Verwendung von Globals das Programm für die Leser klarer gemacht . Indem der ursprüngliche Programmierer sich gedankenlos an das Wort der Regel hielt, hatte er die Absicht der Regel verfehlt.
Also, ja, Globale sind oft schlecht. Wenn Sie jedoch der Meinung sind, dass die Absicht des Programmierers am Ende durch die Verwendung globaler Variablen klarer wird, fahren Sie fort. Denken Sie jedoch an den Rückgang der Klarheit, der automatisch auftritt, wenn Sie jemanden zwingen, auf einen zweiten Code (die Globals) zuzugreifen, um zu verstehen, wie der erste Teil funktioniert.
Mein Professor sagte immer so etwas wie: Die Verwendung globaler Variablen ist in Ordnung, wenn Sie sie richtig verwenden. Ich glaube nicht, dass ich jemals gut darin geworden bin, sie richtig zu benutzen, deshalb habe ich sie selten benutzt.
static
globale Variablen, die Sprache ist C. Da sie auf relativ kleine Übersetzungseinheiten beschränkt sind, ähneln sie Klassenvariablen von C ++ - Objekten.
program lifetime, file scope variables
. Und sie werden ziemlich global, sobald Sie einen Zeiger auf die Variable nach außen übergeben (was mit automatischen Variablen unmöglich ist).
static
globale Variablen haben einen begrenzten Umfang für dieselbe Übersetzungseinheit. Sie haben jedoch eine Lebensdauer bis zum Ende des Programms wie jede globale Variable.
Globale Variablen sollten nur verwendet werden, wenn Sie keine Alternative haben. Und ja, dazu gehören auch Singletons. In 90% der Fälle werden globale Variablen eingeführt, um die Kosten für die Weitergabe eines Parameters zu sparen. Und dann passiert Multithreading / Unit-Test / Wartungscodierung, und Sie haben ein Problem.
Also ja, in 90% der Situationen sind globale Variablen schlecht. Die Ausnahmen werden von Ihnen in Ihren Studienjahren wahrscheinlich nicht gesehen. Eine Ausnahme, die ich mir vorstellen kann, ist der Umgang mit inhärent globalen Objekten wie Interrupt-Tabellen. Dinge wie die DB-Verbindung scheinen global zu sein, sind es aber nicht.
Das Problem, das globale Variablen für den Programmierer erzeugen, besteht darin, dass die Kopplungsfläche zwischen den Komponenten zwischen den verschiedenen Komponenten, die die globalen Variablen verwenden, erweitert wird. Dies bedeutet, dass mit zunehmender Anzahl von Komponenten, die eine globale Variable verwenden, auch die Komplexität der Interaktionen zunehmen kann. Diese erhöhte Kopplung erleichtert normalerweise das Einspritzen von Fehlern in das System, wenn Änderungen vorgenommen werden, und erschwert auch die Diagnose und Korrektur von Fehlern. Diese Erhöhung der Kopplung kann auch die Anzahl der verfügbaren Optionen beim Vornehmen von Änderungen verringern und den Aufwand für Änderungen erhöhen, da häufig die verschiedenen Module durchlaufen werden müssen, die auch die globale Variable verwenden, um die Folgen von Änderungen zu bestimmen.
Der Zweck der Kapselung , die im Grunde das Gegenteil der Verwendung globaler Variablen ist, besteht darin, die Kopplung zu verringern, um das Verständnis und den Wechsel der Quelle einfacher und sicherer zu machen und leichter zu testen. Es ist viel einfacher, Unit-Tests zu verwenden , wenn keine globalen Variablen verwendet werden.
Wenn Sie beispielsweise eine einfache globale Ganzzahlvariable haben, die als Aufzählungsindikator verwendet wird, den verschiedene Komponenten als Zustandsmaschine verwenden, und Sie dann eine Änderung vornehmen, indem Sie einen neuen Zustand für eine neue Komponente hinzufügen, müssen Sie alle anderen nachverfolgen Komponenten, um sicherzustellen, dass die Änderung keine Auswirkungen auf sie hat. Ein Beispiel für ein mögliches Problem wäre, wenn eine switch
Anweisung zum Testen des Werts der globalen Aufzählungsvariablen mit case
Anweisungen für jeden der aktuellen Werte an verschiedenen Stellen verwendet wird und es daher vorkommt, dass einige der switch
Anweisungen keinen default
zu behandelnden Fall haben Ein unerwarteter Wert für das Globale. Plötzlich haben Sie ein undefiniertes Verhalten in Bezug auf die Anwendung.
Andererseits kann die Verwendung eines gemeinsam genutzten Datenbereichs verwendet werden, um einen Satz globaler Parameter zu enthalten, auf die in der gesamten Anwendung verwiesen wird. Dieser Ansatz wird häufig bei eingebetteten Anwendungen mit geringem Speicherbedarf verwendet.
Wenn Sie globale Variablen in solchen Anwendungen verwenden, wird die Verantwortung für das Schreiben in den Datenbereich normalerweise einer einzelnen Komponente zugewiesen, und alle anderen Komponenten sehen den Bereich als const
und lesen aus ihm und schreiben niemals in ihn. Dieser Ansatz begrenzt die Probleme, die entstehen können.
Einige Probleme mit globalen Variablen, die umgangen werden müssen
Wenn die Quelle für eine globale Variable wie eine Struktur geändert wird, muss alles, was sie verwendet, neu kompiliert werden, damit alles, was die Variable verwendet, ihre wahre Größe und Speichervorlage kennt.
Wenn mehr als eine Komponente die globale Variable ändern kann, können Probleme mit inkonsistenten Daten in der globalen Variablen auftreten. Bei einer Multithreading-Anwendung müssen Sie wahrscheinlich eine Art Sperre oder einen kritischen Bereich hinzufügen, um eine Möglichkeit bereitzustellen, dass jeweils nur ein Thread die globale Variable ändern kann. Wenn ein Thread die Variable ändert, sind alle Änderungen abgeschlossen und festgeschrieben, bevor andere Threads die Variable abfragen oder ändern können.
Das Debuggen einer Multithread-Anwendung, die eine globale Variable verwendet, kann schwieriger sein. Sie können auf Rennbedingungen stoßen, die zu Fehlern führen können, die schwer zu replizieren sind. Da mehrere Komponenten über eine globale Variable kommunizieren, insbesondere in einer Multithread-Anwendung, kann es sehr schwierig sein zu wissen, welche Komponente die Variable wann und wie sie die Variable ändert.
Namenskonflikte können ein Problem bei der Verwendung globaler Variablen sein. Eine lokale Variable, die denselben Namen wie eine globale Variable hat, kann die globale Variable ausblenden. Bei Verwendung der Programmiersprache C tritt auch das Problem der Namenskonvention auf. Eine Problemumgehung besteht darin, das System in Subsysteme mit den globalen Variablen für ein bestimmtes Subsystem aufzuteilen, die alle mit denselben ersten drei Buchstaben beginnen (siehe dies zum Auflösen von Namensraumkollisionen in Ziel C ). C ++ bietet Namespaces, und mit C können Sie dies umgehen, indem Sie eine global sichtbare Struktur erstellen, deren Mitglieder verschiedene Datenelemente und Zeiger auf Daten und Funktionen sind, die in einer Datei als statisch bereitgestellt werden, daher nur mit Dateisichtbarkeit, sodass nur auf sie verwiesen werden kann die global sichtbare Struktur.
In einigen Fällen wird die ursprüngliche Anwendungsabsicht geändert, sodass globale Variablen, die den Status für einen einzelnen Thread bereitgestellt haben, so geändert werden, dass mehrere doppelte Threads ausgeführt werden können. Ein Beispiel wäre eine einfache Anwendung, die für einen einzelnen Benutzer entwickelt wurde und globale Variablen für den Status verwendet. Anschließend wird vom Management eine Anforderung zum Hinzufügen einer REST-Schnittstelle gesendet , damit Remoteanwendungen als virtuelle Benutzer fungieren können. Jetzt müssen Sie die globalen Variablen und ihre Statusinformationen duplizieren, damit sowohl der einzelne Benutzer als auch jeder der virtuellen Benutzer aus Remoteanwendungen über einen eigenen, eindeutigen Satz globaler Variablen verfügen.
Verwenden von C ++ namespace
und der struct
Technik für C.
Für die Programmiersprache C ++ ist die namespace
Direktive eine große Hilfe, um die Wahrscheinlichkeit eines Namenskonflikts zu verringern. namespace
zusammen mit class
und die verschiedenen Zugriffs Schlüsselwörter ( private
, protected
und public
) bieten die meisten der Werkzeuge , die Sie zu verkapseln Variablen benötigen. Die Programmiersprache C bietet diese Anweisung jedoch nicht. Diese Stapelüberlauf-Veröffentlichung, Namespaces in C , bietet einige Techniken für C.
Eine nützliche Technik besteht darin, einen einzelnen speicherresidenten Datenbereich zu haben, der als struct
global definierter Bereich definiert ist und in dem struct
Zeiger auf die verschiedenen globalen Variablen und Funktionen enthalten sind, die verfügbar gemacht werden. Die tatsächlichen Definitionen der globalen Variablen werden mit dem static
Schlüsselwort als Dateibereich angegeben . Wenn Sie dann das const
Schlüsselwort verwenden, um anzugeben, welche schreibgeschützt sind, kann der Compiler Ihnen helfen, den schreibgeschützten Zugriff zu erzwingen.
Die Verwendung der struct
Technik kann auch das Globale kapseln, so dass es zu einer Art Paket oder Komponente wird, die zufällig ein Globales ist. Durch eine solche Komponente wird es einfacher, Änderungen, die sich auf das Globale und die Funktionalität auswirken, mithilfe des Globalen zu verwalten.
Während namespace
oder die struct
Technik dabei helfen kann, Namenskonflikte zu verwalten, bestehen immer noch die zugrunde liegenden Probleme der Kopplung zwischen Komponenten, die die Verwendung von Globals insbesondere in einer modernen Multithread-Anwendung mit sich bringt.
Globale Variablen sind genauso schlecht wie Sie sie machen, nicht weniger.
Wenn Sie ein vollständig gekapseltes Programm erstellen, können Sie Globals verwenden. Es ist eine "Sünde", Globale zu benutzen, aber Programmiersünden sind größtenteils philosophisch.
Wenn Sie L.in.oleum auschecken , sehen Sie eine Sprache, deren Variablen ausschließlich global sind. Es ist nicht skalierbar, da alle Bibliotheken keine andere Wahl haben, als Globals zu verwenden.
Das heißt, wenn Sie die Wahl haben und die Programmiererphilosophie ignorieren können, sind Globals gar nicht so schlecht.
Gotos auch nicht, wenn Sie sie richtig verwenden.
Das große "schlechte" Problem ist, dass, wenn man sie falsch benutzt, die Leute schreien, der Marslander abstürzt und die Welt in die Luft sprengt ... oder so ähnlich.
Ja, aber die Kosten für globale Variablen fallen erst an, wenn Sie aufhören, in dem Code zu arbeiten, der globale Variablen verwendet, und etwas anderes schreiben, das den Code verwendet, der globale Variablen verwendet. Aber die Kosten sind immer noch da.
Mit anderen Worten, es sind langfristige indirekte Kosten und als solche denken die meisten Leute, dass es nicht schlecht ist.
Wenn es möglich ist, dass Ihr Code während eines Prozesses vor dem Obersten Gerichtshof einer intensiven Überprüfung unterzogen wird , sollten Sie sicherstellen, dass globale Variablen vermieden werden.
Siehe diesen Artikel: Der Buggy-Alkoholtester-Code spiegelt die Bedeutung der Quellenüberprüfung wider
Es gab einige Probleme mit dem Stil des Codes, die von beiden Studien identifiziert wurden. Eines der stilistischen Probleme, die die Prüfer betrafen, war die weitgehende Verwendung ungeschützter globaler Variablen . Dies wird als schlechte Form angesehen, da es das Risiko erhöht, dass der Programmstatus inkonsistent wird oder dass Werte versehentlich geändert oder überschrieben werden. Die Forscher äußerten sich auch besorgt über die Tatsache, dass die Dezimalgenauigkeit im gesamten Code nicht konsistent bleibt.
Mann, ich wette, diese Entwickler wünschen sich, sie hätten keine globalen Variablen verwendet!
Ich würde diese Frage mit einer anderen Frage beantworten: Verwenden Sie Singeltons / Sind Singeltons schlecht?
Weil (fast alle) Singelton-Nutzung eine verherrlichte globale Variable ist.
Das Problem ist weniger, dass sie schlecht sind , als vielmehr, dass sie gefährlich sind . Sie haben ihre eigenen Vor- und Nachteile, und es gibt Situationen, in denen sie entweder die effizienteste oder die einzige Möglichkeit sind, eine bestimmte Aufgabe zu erfüllen. Sie sind jedoch sehr leicht zu missbrauchen, selbst wenn Sie Schritte unternehmen, um sie immer richtig zu verwenden.
Ein paar Profis:
Ein paar Nachteile:
Beachten Sie, wenn Sie so wollen, dass die ersten beiden Vor- und Nachteile, die ich aufgelistet habe, genau dasselbe sind, nur mit unterschiedlichem Wortlaut. Dies liegt daran, dass die Funktionen einer globalen Variablen zwar nützlich sein können, aber genau die Funktionen, die sie nützlich machen, sind die Ursache all ihrer Probleme.
Einige mögliche Lösungen für einige der Probleme:
Globals
oder GlobalVars
) oder verwenden Sie eine standardisierte Namenskonvention für globale Variablen (wie global_[name]
oder g_module_varNameStyle
(wie von underscore_d in den Kommentaren erwähnt) )). Dies dokumentiert sowohl ihre Verwendung (Sie können Code finden, der globale Variablen verwendet, indem Sie nach dem Namespace / Strukturnamen suchen) als auch die Auswirkungen auf den globalen Namespace zu minimieren.extern
im zugehörigen Header, sodass ihre Verwendung auf Kompilierungseinheiten beschränkt werden kann, die auf sie zugreifen müssen. Wenn Ihr Code auf vielen globalen Variablen basiert, aber jede Kompilierungseinheit nur Zugriff auf eine Handvoll davon benötigt, können Sie sie in mehrere Quelldateien sortieren, sodass der Zugriff jeder Datei auf globale Variablen einfacher eingeschränkt werden kann.Ob sie gut oder schlecht sind, hängt davon ab, wie Sie sie verwenden. Die Mehrheit neigt dazu, sie schlecht zu benutzen, daher die allgemeine Vorsicht gegenüber ihnen. Bei richtiger Anwendung können sie ein großer Segen sein. Wenn sie jedoch schlecht verwendet werden, können und werden sie zurückkommen, um Sie zu beißen, wann und wie Sie es am wenigsten erwarten.
Eine gute Sichtweise ist, dass sie selbst nicht schlecht sind, aber schlechtes Design ermöglichen und die Auswirkungen von schlechtem Design exponentiell vervielfachen können.
Selbst wenn Sie nicht beabsichtigen, sie zu verwenden, ist es besser zu wissen, wie man sie sicher verwendet und sich dagegen entscheidet, als sie nicht zu verwenden, da Sie nicht wissen, wie Sie sie sicher verwenden sollen. Wenn Sie sich jemals in einer Situation befinden, in der Sie bereits vorhandenen Code pflegen müssen, der auf globalen Variablen basiert, können Sie Schwierigkeiten haben, wenn Sie nicht wissen, wie Sie sie richtig verwenden sollen.
g_module_varNameStyle
perfekt lesbar. Um es klar auszudrücken, ich verwende keine Globals, wenn ich es leicht vermeiden kann - Schlüsselwort leicht , denn da ich aufgehört habe zu glauben, dass sie um jeden Preis vermieden oder eher verschleiert werden müssen, habe ich eine viel bessere Zeit und meine Code ist (Schock!) viel aufgeräumter
Wie jemand in einem anderen Thread sagte (ich paraphrasiere) "Regeln wie diese sollten nicht gebrochen werden, bis Sie die Konsequenzen vollständig verstanden haben."
Es gibt Zeiten, in denen globale Variablen notwendig oder zumindest sehr hilfreich sind (z. B. Arbeiten mit systemdefinierten Rückrufen). Andererseits sind sie aus all den Gründen, die Ihnen mitgeteilt wurden, auch sehr gefährlich.
Es gibt viele Aspekte der Programmierung, die wahrscheinlich den Experten überlassen werden sollten. Manchmal braucht man ein sehr scharfes Messer. Aber Sie können erst dann einen verwenden, wenn Sie bereit sind ...
Globale Variablen sind im Allgemeinen schlecht, insbesondere wenn andere Personen an demselben Code arbeiten und nicht 20 Minuten damit verbringen möchten, nach allen Stellen zu suchen, auf die die Variable verweist. Das Hinzufügen von Threads, die die Variablen ändern, bringt ein völlig neues Maß an Kopfschmerzen mit sich.
Globale Konstanten in einem anonymen Namespace, die in einer einzelnen Übersetzungseinheit verwendet werden, sind in professionellen Apps und Bibliotheken in Ordnung und allgegenwärtig. Wenn die Daten jedoch veränderlich sind und / oder von mehreren TUs gemeinsam genutzt werden müssen, möchten Sie sie möglicherweise kapseln - wenn nicht aus Gründen des Designs, dann aus Gründen des Debuggens oder der Arbeit mit Ihrem Code.
Die Verwendung globaler Variablen ist so, als würde man Schmutz unter einen Teppich kehren. Es ist eine schnelle Lösung und kurzfristig viel einfacher, als eine Kehrschaufel oder einen Staubsauger zum Reinigen zu bekommen. Wenn Sie den Teppich jedoch später bewegen, wird es eine große Überraschung geben.
Ich denke, Ihr Professor versucht, eine schlechte Angewohnheit zu beenden, bevor sie überhaupt beginnt.
Globale Variablen haben ihren Platz und wie viele Leute sagten, kann es kompliziert sein zu wissen, wo und wann sie verwendet werden sollen. Ich denke also, anstatt sich mit dem Warum, Wie, Wann und Wo globaler Variablen zu befassen, hat Ihr Professor beschlossen, nur zu verbieten. Wer weiß, er könnte sie in Zukunft verbieten.
Absolut nicht. Sie zu missbrauchen ... das ist schlecht.
Das sinnlose Entfernen ist nur das ... sinnlos. Wenn Sie die Vor- und Nachteile nicht kennen, ist es am besten, klar zu steuern und das zu tun, was Sie gelernt haben, aber mit globalen Variablen ist nichts implizit falsch. Wenn Sie die Vor- und Nachteile besser verstehen, treffen Sie Ihre eigene Entscheidung.
Globale Variablen sind in kleinen Programmen in Ordnung, aber schrecklich, wenn sie in großen Programmen auf die gleiche Weise verwendet werden.
Dies bedeutet, dass Sie sich leicht daran gewöhnen können, sie beim Lernen zu verwenden. Darum versucht Ihr Professor Sie zu schützen.
Wenn Sie erfahrener sind, ist es einfacher zu lernen, wann sie in Ordnung sind.
Nein, sie sind überhaupt nicht schlecht. Sie müssen sich den vom Compiler erzeugten (Maschinen-) Code ansehen, um diese Feststellung zu treffen. Manchmal ist es weitaus schlimmer, einen lokalen als einen globalen Code zu verwenden. Beachten Sie auch, dass das Setzen von "statisch" auf eine lokale Variable im Grunde genommen eine globale Variable darstellt (und andere hässliche Probleme verursacht, die eine echte globale lösen würde). "lokale Globale" sind besonders schlecht.
Globals geben Ihnen auch eine saubere Kontrolle über Ihre Speichernutzung, was mit Einheimischen weitaus schwieriger zu tun ist. Heutzutage ist dies nur in eingebetteten Umgebungen von Bedeutung, in denen der Speicher sehr begrenzt ist. Bevor Sie davon ausgehen, dass Embedded mit anderen Umgebungen identisch ist und dass die Programmierregeln in allen Bereichen gleich sind, sollten Sie dies wissen.
Es ist gut, dass Sie die Regeln in Frage stellen, die gelehrt werden. Die meisten davon haben nicht die Gründe, die Ihnen mitgeteilt werden. Die wichtigste Lektion ist jedoch nicht, dass dies eine Regel ist, die Sie für immer bei sich tragen müssen, sondern eine Regel, die Sie einhalten müssen, um diese Klasse zu bestehen und voranzukommen. Im Leben werden Sie feststellen, dass Sie für die Firma XYZ andere Programmierregeln haben, die Sie am Ende einhalten müssen, um weiterhin einen Gehaltsscheck zu erhalten. In beiden Situationen können Sie die Regel argumentieren, aber ich denke, Sie werden bei einem Job viel mehr Glück haben als in der Schule. Sie sind nur ein weiterer von vielen Studenten, Ihr Sitz wird bald ersetzt, die Professoren nicht, bei einem Job gehören Sie zu einem kleinen Team von Spielern, die dieses Produkt bis zum Ende sehen müssen, und in diesem Umfeld gelten die Regeln für die Nutzen der Teammitglieder sowie des Produkts und des Unternehmens, Wenn also jeder gleichgesinnt ist oder wenn es für das jeweilige Produkt einen guten technischen Grund gibt, gegen etwas zu verstoßen, das Sie im College gelernt haben, oder gegen ein Buch über generische Programmierung, dann verkaufen Sie Ihre Idee an das Team und schreiben Sie sie als gültige, wenn nicht bevorzugte Methode auf . In der realen Welt ist alles Freiwild.
Wenn Sie alle Programmierregeln befolgen, die Ihnen in der Schule oder in Büchern beigebracht wurden, ist Ihre Programmierkarriere äußerst begrenzt. Sie können wahrscheinlich überleben und eine fruchtbare Karriere haben, aber die Breite und Breite der Umgebungen, die Ihnen zur Verfügung stehen, sind äußerst begrenzt. Wenn Sie wissen, wie und warum die Regel da ist und sie verteidigen kann, ist das gut, wenn Sie nur Grund haben, "weil mein Lehrer es gesagt hat", dann ist das nicht so gut.
Beachten Sie, dass Themen wie diese häufig am Arbeitsplatz diskutiert werden und auch weiterhin behandelt werden, wenn sich Compiler und Prozessoren (und Sprachen) weiterentwickeln. Dies gilt auch für diese Art von Regeln, ohne Ihre Position zu verteidigen und möglicherweise von jemandem mit einer anderen Meinung unterrichtet zu werden, die Sie nicht kennen vorwärts bewegen.
In der Zwischenzeit tun Sie einfach, was derjenige sagt, der am lautesten spricht oder den größten Stock trägt (bis Sie derjenige sind, der am lautesten schreit und den größten Stock trägt).
Ich möchte gegen den Punkt argumentieren, der in diesem Thread angesprochen wird, dass es Multithreading per se schwieriger oder unmöglich macht. Globale Variablen sind gemeinsame Zustände, aber die Alternativen zu globalen Variablen (z. B. das Weitergeben von Zeigern) können auch den gemeinsamen Zustand haben. Das Problem beim Multithreading besteht darin, wie der gemeinsam genutzte Status ordnungsgemäß verwendet wird und nicht, ob dieser Status zufällig über eine globale Variable oder etwas anderes gemeinsam genutzt wird.
Meistens müssen Sie beim Multithreading etwas freigeben. In einem Producer-Consumer-Muster können Sie beispielsweise eine thread-sichere Warteschlange freigeben, die die Arbeitseinheiten enthält. Und Sie dürfen es teilen, weil diese Datenstruktur threadsicher ist. Ob diese Warteschlange global ist oder nicht, ist für die Thread-Sicherheit völlig irrelevant.
Die implizite Hoffnung, die in diesem Thread zum Ausdruck gebracht wird, dass die Umwandlung eines Programms von Single-Threaded in Multi-Threaded einfacher ist, wenn keine Globals verwendet werden, ist naiv. Ja, Globale machen es einfacher, sich in den Fuß zu schießen, aber es gibt viele Möglichkeiten, sich selbst zu schießen.
Ich befürworte keine globalen Punkte, da die anderen Punkte immer noch bestehen. Mein Punkt ist lediglich, dass die Anzahl der Threads in einem Programm nichts mit dem variablen Umfang zu tun hat.
Ja, denn wenn Sie inkompetente Programmierer verwenden lassen (lesen Sie 90%, insbesondere Wissenschaftler), erhalten Sie mehr als 600 globale Variablen, die auf mehr als 20 Dateien verteilt sind, und ein Projekt mit 12.000 Zeilen, bei dem 80% der Funktionen ungültig werden, ungültig werden und ausgeführt werden ganz auf den globalen Staat.
Es wird schnell unmöglich zu verstehen, was zu einem bestimmten Zeitpunkt vor sich geht, wenn Sie nicht das gesamte Projekt kennen.
Die Verwendung globaler Variablen hängt tatsächlich von den Anforderungen ab. Der Vorteil besteht darin, dass der Aufwand für die wiederholte Übergabe der Werte verringert wird.
Ihr Professor hat jedoch Recht, da dies Sicherheitsprobleme aufwirft. Daher sollte die Verwendung globaler Variablen so weit wie möglich vermieden werden. Globale Variablen verursachen auch Probleme, die manchmal schwer zu debuggen sind .
Beispielsweise:-
Situationen, in denen die Variablenwerte zur Laufzeit geändert werden . In diesem Moment ist es schwierig zu identifizieren, welcher Teil des Codes ihn unter welchen Bedingungen ändert.
Global sind gut, wenn es um Konfiguration geht . Wenn wir unsere wollen Konfiguration / Änderungen eine haben globalen Auswirkungen auf gesamtes Projekt .
Wir können also eine Konfiguration ändern und die Änderungen beziehen sich auf das gesamte Projekt . Aber ich muss warnen, dass Sie sehr klug sein müssen, um Globals zu verwenden.
Früher oder später müssen Sie ändern, wie diese Variable festgelegt wird oder was passiert, wenn auf sie zugegriffen wird, oder Sie müssen nur herausfinden, wo sie geändert wird.
Es ist praktisch immer besser, keine globalen Variablen zu haben. Schreiben Sie einfach die Methoden zum Erhalten und Festlegen des Damms und lassen Sie sich dröhnen, wenn Sie sie einen Tag, eine Woche oder einen Monat später benötigen.
Normalerweise verwende ich Globals für Werte, die selten geändert werden, wie Singletons oder Funktionszeiger auf Funktionen in einer dynamisch geladenen Bibliothek. Die Verwendung von veränderlichen Globals in Multithread-Anwendungen führt in der Regel zu schwer zu verfolgenden Fehlern. Daher versuche ich, dies in der Regel zu vermeiden.
Die Verwendung einer globalen Anwendung anstelle der Übergabe eines Arguments ist häufig schneller. Wenn Sie jedoch eine Multithread-Anwendung schreiben, wie Sie dies heutzutage häufig tun, funktioniert dies im Allgemeinen nicht sehr gut (Sie können Thread-Statik verwenden, aber dann ist der Leistungsgewinn fraglich). .
In Webanwendungen kann ein Unternehmen verwendet werden, um aus Optimierungsgründen Sitzungs- / Fenster- / Thread- / benutzerspezifische Daten auf dem Server zu speichern und Arbeitsausfälle bei instabilen Verbindungen zu vermeiden. Wie bereits erwähnt, müssen die Rennbedingungen behandelt werden. Wir verwenden eine einzelne Instanz einer Klasse für diese Informationen und sie werden sorgfältig verwaltet.
Am Ende des Tages kann Ihr Programm oder Ihre App immer noch funktionieren, aber es geht darum, aufgeräumt zu sein und ein umfassendes Verständnis dafür zu haben, was vor sich geht. Wenn Sie einen variablen Wert für alle Funktionen freigeben, kann es schwierig werden, festzustellen, welche Funktion den Wert ändert (wenn die Funktion dies tut), und das Debuggen wird millionenfach schwieriger
Sicherheit ist weniger bedeutet, dass jeder die Variablen manipulieren kann, wenn sie als global deklariert sind. Um dies zu erläutern, nehmen Sie dieses Beispiel, wenn Sie ein Guthaben als globale Variable in Ihrem Bankprogramm haben. Die Benutzerfunktion kann dies manipulieren, und der Bankangestellte kann es auch manipulieren Dies ist ein Problem. Nur der Benutzer sollte die Funktion "Nur Lesen" und "Abheben" erhalten, aber der Bankangestellte kann den Betrag hinzufügen, wenn der Benutzer das Geld persönlich am Schreibtisch ausgibt. So funktioniert es
Verwenden Sie in einer Multithread-Anwendung lokale Variablen anstelle globaler Variablen, um eine Race-Bedingung zu vermeiden.
Eine Race-Bedingung tritt auf, wenn mehrere Threads auf eine gemeinsam genutzte Ressource zugreifen, wobei mindestens ein Thread Schreibzugriff auf die Daten hat. Dann ist das Ergebnis des Programms nicht vorhersehbar und hängt von der Reihenfolge der Zugriffe auf die Daten durch verschiedene Threads ab.
Mehr dazu hier, https://software.intel.com/en-us/articles/use-intel-parallel-inspector-to-find-race-conditions-in-openmp-based-multithreaded-code