Poniższy program pokazuje, że możemy użyć funkcji return() lub pthread_exit(), aby zwrócić zmienną void * dostępną dla zmiennej stanu pthread_join().return() versus pthread_exit() w funkcjach start pthread
(1) Czy należy preferować korzystanie z jednego nad drugim?
(2) Dlaczego korzysta z funkcji return()? Normalnie myślimy o powrocie, umieszczając wartość na stosie, ale ponieważ wątek jest zakończony, stos powinien zniknąć. Czy też stos nie zostanie zniszczony przed pthread_join()?
(3) Czy w swojej pracy widzisz duże wykorzystanie zmiennej status? Wygląda na to, że 90% kodu, który widzę, po prostu NULL określa parametr statusu. Ponieważ wszystko, co zmieniło się poprzez pustkę * ptr, jest już odzwierciedlone w wątku wywołującym, nie ma sensu zwracać go. Każda nowa void * ptr zwrócony musi wskazywać na coś zdezynfekowanego przez wątek początkowy, który pozostawia odbierający wątek z obowiązkiem usunięcia go. Czy myliłem się sądząc, że zmienna statusu jest bezcelowa?
#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;
}
o mocy:
before 10 10 Hello
after task1 35 5.5 Goodbye
after task2 10 10 World
Jeśli chodzi o (1), pthread_exit nie kończy natychmiast wątku, uruchamia procedury obsługi anulowania. Przynajmniej NPTL/g ++ używa tego samego mechanizmu dla procedur obsługi anulowania i C++, więc pthread_exit faktycznie odwija stos w tym przypadku. Podobnie, OpenVMS pthread_exit/anulowanie wątku rozwija stos i działa z C++. Powinieneś prawdopodobnie sprawdzić instrukcję dla Twojej konkretnej implementacji pthread w odniesieniu do zachowania pthread_exit i rozwijania stosu. –
Wyjaśniłem (1), aby uwzględnić twój komentarz. –
Zdecydowanie kupuję twoją książkę :) (mam nadzieję, że wkrótce wyjdzie). – celavek