Forum: PC-Programmierung Problem mit pthread und globalen Variablen


von Coco J. (Gast)


Lesenswert?

Schönen guten Tag,

ich Programmierem momentan an einem Programm für die Umgebung QNX.

Das Projekt ist schon sehr weit fortgeschritten, und es gibt momentan 
ein Problem.


--------------------                   -----------------
| Empfänger        |         ->        | int pid = ... |
-------------------- Initlialisierung  -----------------
         |                                    /\
         | Empfang                             |
         |                                     |
        \/                                     |
---------------------                          |
|  qthread_create() |                          |
|  -> bewege()      |---------> greift zu ---- |
---------------------


Der Empfänger initialisiert mehrer Verbindungen zu anderen Servern. 
Hierbei wird die ID der Verbindung in globalen Variablen 
zwischengespeichert, so dass die ID nicht bei jedem Funktionsaufruf 
übergeben werden muss.

Die globalen Variablen werden in der untersten Softwareschicht 
definiert.
(sozusagen die Treiber).

Nach der Initialisung befindet sich der Server im Empfangsmodus. Wird 
eine
Nachricht empfangen, startet der Server einen Thread und antwortet obs 
möglich war.

Die Threads sind wichtig, da der Server immer empfangsbereit sein soll 
und nicht in einen blockierten Zustand wechseln darf.

Das Problem ist nun, wenn ich aus einem Thread (indirekt über 
Funktionsaufrufe) auf die globale Variable zugreife, ist dort scheinbar 
nicht der richtige Wert drin.

Weiß jemand, was ich ändern muss, damit die Variable in dem neuen Thread 
anständig genutzt werden kann?

von Hans (Gast)


Lesenswert?

evt Semaphoren nutzen

von (prx) A. K. (prx)


Lesenswert?

Je nach konkretem Ablauf kann es notwendig sein, solche Variablen als 
volatile zu deklarieren. Allerdings kann - wenn häufig verwendet - die 
nicht-volatile Übergabe per Parameter effizienter sein als eine globale 
volatile Variable.

: Bearbeitet durch User
von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Volatile, wie schon angemerkt, ist wichtig, wenn aus zwei Threads auf 
die gleiche Variable zugegriffen werden soll, und atomaren Zugriff 
sicherstellen.
Das geht u.a. mit Synchronisatonsobjekten wie Semaphoren oder Mutexen.

Es gibt Betriebssysteme, die zusätzlich zu prozessübergreifenden 
Synchronisationsobjekten auch welche zur Verfügung stellen, die nur von 
den Threads eines Prozesses verwendet werden können, was weniger 
Overhead zur Folge hat. Ob es so etwas bei QNX gibt, wirst Du selbst 
herausfinden müssen.

von Coco J. (Gast)


Lesenswert?

Danke für die Vorschläge, ich werd mich mal mit dem synchronisiertem 
Objekt beschäftigen.

Auf mysteriöse Art und Weise funktioniert jetzt alles,.. warum auch 
immer (die IDE ist sehr launisch..)

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

coco jack schrieb:
> warum auch immer (die IDE ist sehr launisch..)

Threads sind asyncron, d.h. zwei durchläufe müssen nicht zwangsläufig 
die gleiche Zeitliche Abfolge haben, zu deiner Frage

coco jack schrieb:
> was ich ändern muss, damit die Variable in dem neuen Thread anständig
> genutzt werden kann?

Jeder Thread hat seine ID, globale Variablen sind im Context von Threads 
ein Stolperstein wie du schon festgestellt hast, das:

coco jack schrieb:
> Hierbei wird die ID der Verbindung in globalen Variablen
> zwischengespeichert, so dass die ID nicht bei jedem Funktionsaufruf
> übergeben werden muss.

Hört sich arg danach an als würdest du einmal EINE globale Variable mit 
einer ID belegen und dann mehrere Funktionen aufrufen welche diese 
auslesen. Das geht mit ziemlicher Sicherheit in die Grütze. (Und 
Sempahoren o.ä. helfen da auch nicht, dann kann man gleich 
SingleThreaded fahren).

coco jack schrieb:
> Die Threads sind wichtig, da der Server immer empfangsbereit sein soll
> und nicht in einen blockierten Zustand wechseln darf

Das kann man nicht nur mit Threads erreichen.

von schnitzel (Gast)


Lesenswert?

Wenn die globale ID einmalig gesetzt wird
und dann unverändert bleibt
und danach irgendein Thread gestartet wird,
muss der Thread den korrekten Wert bekommen - auch ohne volatile.
Auch bzgl. "caching" ist das OK, da das Starten des Threads quasi als 
Barrier gewertet wird.

Sollte die ID jedoch von mehreren Threads geändert werden können, muss 
dies z.B. mit einem mutex (pthread_mutex) geschützt werden, um
a) nicht gleichzeitig darauf zugreifen zu können und
b) um damit dem Compiler/System klar zu machen, dass möglicherweise eine 
Änderung erfolgt ist - auch hier ist volatile IMHO nicht erforderlich 
(aber übersichtlicher/verständlicher) da dies implizit durch den Mutex 
sichergestellt ist und vom Compiler berücksichtig wird.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.