Threads unter Linux
-
Hallo!
Ich programmiere derzeit ein C++ Webapplikation für einen Windows- und einen Linuxserver. Die App arbeitet mit Threads. Da ich noch nicht wirklich viel für Linux programmiert (außer ISO-C++) und schon gar nichts threadlastiges wollte ich mich versichern ob die richigen Funktionen nutze und deren Verwendung korrekt ist.
Unter Windows nutzen ichCreateThread TerminateThread WaitForMultipleObjects
Für Linux habe ich mir Pendaten (gleiche Reihenfolge) herausgesucht
pthread_create pthread_cancel pthread_join
Nun der Code für das Linuxsystem:
// ThreadProc für Linux void * ThreadProc1 (void *lpContentCtx) { struct XCtx *pctx = reinterpret_cast<XCtx*>(lpContentCtx); // Code... return NULL; } void * ThreadProc2 (void *lpContentCtx) { struct XCtx *pctx = reinterpret_cast<XCtx*>(lpContentCtx); // Code... return NULL; } void StartThreads(void) { pthread_t thThread1 = 0, thThread2 = 0; // Thread 1 starten if (pthread_create(&thThread1, NULL, ThreadProc1, reinterpret_cast<void*>(&MyXCtx1)) != 0) { return false; } // Thread 2 starten if (pthread_create(&thThread2, NULL, ThreadProc2, reinterpret_cast<void*>(&MyXCtx2)) != 0) { pthread_cancel(thThread1); return false; } // Auf Threads warten pthread_join(thThread1, NULL); pthread_join(thThread2, NULL); return true; }
Habe bisher noch keine Möglichkeit gehabt den Code zu testen. Wird warscheinlich erst morgen etwas. Mir geht es erstmal nur darum ob ich die entschsprechenden OS Funktionen korrekt portiert haben.
-
Sieht auf den ersten Blick korrekt aus. Allerdings müssen die Thread-Starter (da die pthread-API eine C-API ist) unbedingt in einen extern "C" {} Block eingeschlossen werden, sonst könnte es bei den Calling Conventions knallen (aktuell wird das mit keinem GCC passieren, aber laut Standard darf es passieren, also lieber sicher gehen).
(Rein formal werden bei Deinen pthread_join Aufrufen die falschen Variablen verwendet!)
-
LordJaxom schrieb:
Sieht auf den ersten Blick korrekt aus. Allerdings müssen die Thread-Starter (da die pthread-API eine C-API ist) unbedingt in einen extern "C" {} Block eingeschlossen werden, sonst könnte es bei den Calling Conventions knallen (aktuell wird das mit keinem GCC passieren, aber laut Standard darf es passieren, also lieber sicher gehen).
Hmm. Nun gut. Würde dann so aussehen, oder?
// ThreadProc für Linux void * ThreadProc1 (void *lpContentCtx) { struct XCtx *pctx = reinterpret_cast<XCtx*>(lpContentCtx); // Code... return NULL; } void * ThreadProc2 (void *lpContentCtx) { struct XCtx *pctx = reinterpret_cast<XCtx*>(lpContentCtx); // Code... return NULL; } extern "C" { void StartThreads(void) { pthread_t thThread1 = 0, thThread2 = 0; // Thread 1 starten if (pthread_create(&thThread1, NULL, ThreadProc1, reinterpret_cast<void*>(&MyXCtx1)) != 0) { return false; } // Thread 2 starten if (pthread_create(&thThread2, NULL, ThreadProc2, reinterpret_cast<void*>(&MyXCtx2)) != 0) { pthread_cancel(thThread1); return false; } // Auf Threads warten pthread_join(thThread1, NULL); pthread_join(thThread2, NULL); return true; } } // extern "C"
Habe es ausnahmsweise mal nicht eingerückt.
Ein möglicher Kompileraufruf könnte dann so aussehen:
g++ -D_REENTRANT /* weitere Schalter und Dateien */ -lpthread
LordJaxom schrieb:
(Rein formal werden bei Deinen pthread_join Aufrufen die falschen Variablen verwendet!)
Ups. Danke. Schon geändert.
-
Hups, das war ein Missverständnis
Die Funktionen die von pthread_create als Callback übergeben werden müssen extern "C" sein, nicht die Funktion die pthread_create aufruft
extern "C" { void* ThreadProc1(void* lpData) { /*...*/ } void* ThreadProc2(void* lpData) { /*...*/ } } bool StartThreads(void) { if (pthread_create(&thThread1, NULL, ThreadProc1, reinterpret_cast<void*>(&MyXCtx1)) != 0) { return false; } // Thread 2 starten if (pthread_create(&thThread2, NULL, ThreadProc2, reinterpret_cast<void*>(&MyXCtx2)) != 0) { pthread_cancel(thThread1); return false; } }
-
LordJaxom schrieb:
Hups, das war ein Missverständnis
Die Funktionen die von pthread_create als Callback übergeben werden müssen extern "C" sein, nicht die Funktion die pthread_create aufruft
Huch. Dankeschön.
-
Waitformultipleobjects gibt es unter PThread nicht. Du musst das mit Condition Variablen emulieren.
Soweit ich weiss wird aber Waitformultipleobjects von den Threadinggurus als Designfehler angesehen. Da sollte man eventuell auch unter Windows vorsichtig sein.