Il seguente programma mostra che possiamo usare return() o pthread_exit() per restituire una variabile void * disponibile per la variabile di stato pthread_join().return() rispetto a pthread_exit() nelle funzioni start pthread
(1) È preferibile utilizzare l'uno sull'altro?
(2) Perché utilizzare return() funziona? Normalmente pensiamo di ritornare mettendo un valore nello stack ma dal momento che il thread è completato, lo stack dovrebbe svanire. O lo stack non viene distrutto fino a dopo pthread_join()?
(3) Nel tuo lavoro, vedi molto uso della variabile di stato? Sembra che il 90% del codice veda solo i NULL del parametro di stato. Dal momento che qualsiasi cosa è cambiata tramite il vuoto * ptr si riflette già nel thread chiamante, non sembra che sia necessario rinviarlo. Qualsiasi nuovo void * ptr restituito dovrebbe puntare a qualcosa di malloc-ed dal thread iniziale, che lascia al thread ricevente la responsabilità di eliminarlo. Ho sbagliato a pensare che la variabile di stato sia semi-inutile?
#include <iostream>
#include <pthread.h>
using namespace std;
struct taskdata
{
int x;
float y;
string z;
};
void* task1(void *data)
{
taskdata *t = (taskdata *) data;
t->x += 25;
t->y -= 4.5;
t->z = "Goodbye";
return(data);
}
void* task2(void *data)
{
taskdata *t = (taskdata *) data;
t->x -= 25;
t->y += 4.5;
t->z = "World";
pthread_exit(data);
}
int main(int argc, char *argv[])
{
pthread_t threadID;
taskdata t = {10, 10.0, "Hello"};
void *status;
cout << "before " << t.x << " " << t.y << " " << t.z << endl;
//by return()
pthread_create(&threadID, NULL, task1, (void *) &t);
pthread_join(threadID, &status);
taskdata *ts = (taskdata *) status;
cout << "after task1 " << ts->x << " " << ts->y << " " << ts->z << endl;
//by pthread_exit()
pthread_create(&threadID, NULL, task2, (void *) &t);
pthread_join(threadID, &status);
ts = (taskdata *) status;
cout << "after task2 " << ts->x << " " << ts->y << " " << ts->z << endl;
}
Con uscita:
before 10 10 Hello
after task1 35 5.5 Goodbye
after task2 10 10 World
Riguardo a (1), pthread_exit non termina immediatamente il thread, esegue prima i gestori di annullamento. Almeno NPTL/g ++ usa lo stesso meccanismo per i gestori di cancellazione e gli agenti di comando C++, quindi pthread_exit in effetti risolve lo stack in quel caso. Allo stesso modo, OpenVMS pthread_exit/thread cancellation disattiva lo stack ed esegue i ddt C++. Probabilmente dovresti controllare il manuale per la tua specifica implementazione di pthread per quanto riguarda il comportamento di pthread_exit e lo stack unwinding. –
Ho chiarito (1) per tenere in considerazione il tuo commento. –
Sto definitivamente comprando il tuo libro :) (spero che venga fuori presto). – celavek