Nein, das join kommt woanders hin.
Aber erstmal musst du zwei Typen von Threads unterscheiden:
1) Ein Thread auf den du nicht warten willst und der einfach durchlaufen soll ist ein "Detached" Thread. Ist dieser durch seine Routine gelaufen, dann räumt das OS von alleine auf. Damit ein Thread "Detached" markiert ist, rufst du nach dem pthread_create mit der ThreadId pthread_detach auf:
Code:
#include <stdbool.h>
void RotatePID(uint8_t port, long Target, float RotatSpeed, int8_t cont, bool detach) {
motor[port].runstate=1; // set runstate: PID active
// custom init PID [port]
motor[port].target =Target; // assign target
motor[port].tarpwm =RotatSpeed; // assign rotation speed
motor[port].cont=cont; // cont vs. hit once
// Reset PID control defaults
motor[port].outp =0; // PID control output value
motor[port].maxout =100; // absolute max possible output (max pwr)
motor[port].read =0; // current reading
motor[port].err =0; // current error
motor[port].integr =0; // integral of errors
motor[port].speed =0; // current speed
pthread_create( & motor[port].tid, // id speichern in dem dazugehörigen Array-Element
0, // Default Attribute (threads cancelbar)
PID_calc, // Name der PID-Kalkulationsroutinge
(void*)port); // der Index des Array-Elements für eine PID Struktur,
// die mit dem Motorindex gleich ist.
// Zur Unterscheidung Parameterliste von RotatePID und High-Level-Funktionen erweitern.
if(detach)
pthread_detach(& motor[port].tid);
}
Zu beachten gilt hier noch, dass du so einen Thread nach dem detach nie wieder joinen kannst. Sinvollerweise markierst du das Ende des Threads in der Routine zum Schluss im runstate und setzt die tid wieder auf 0.
2) Bei den anderen Threads die du joinen möchtest mußt du unterscheiden ob du auf das natürliche Ende warten willst oder ob du sie abbrechen (pthread_cancel) möchtest.
In deinem API hattest du eine StopPIDcontroler Funktion, in diese würde ich das optionale cancel und das join implementieren. In etwa so:
Code:
#include <stdbool.h>
void StopPIDcontrol(char port, bool cancel) {
if(cancel)
pthread_cancel(motor[port].tid)
pthread_join(motor[port].tid, 0);
motor[port].tid = 0;
motor[port].runstate = 0;
// und andere Variablen nach dem Ende des Threads setzen
}
Dann hast du eine klare Aufteilung: StopPIDcontrol hält joinable Threads (gewaltsam) an und alle anderen High-Level-Routinen starten einen Thread.
Gruss
botty
P.S. Sinnvollerweise guckst du dir in den man Pages die Rückgabewerte der pthread_ Funktionen an und behandelst noch die möglichen Fehler, das habe ich hier weg gelassen.
Lesezeichen