Unlike some other implementations of threads, C++ destructors for automatic objects are allowed to run in a well defined and consistent manner when a thread is terminated.
The following list includes some of the causes of thread termination:
When a thread terminates, the following occurs:
If a Pthread is terminated using a non-Pthread method (an i5/OS exception, a different thread termination primitive provided by the system, exit() or abort(), or other job termination method), Pthread cancellation cleanup handlers and data destructors do not run.
This example shows the relationship between C++ destructors and Pthread cleanup mechanisms.
See Code disclaimer information for information pertaining to code examples.
#define _MULTI_THREADED #include <stdio.h> #include <qp0z1170.h> #include <time.h> #include <pthread.h> #include "check.h" #define bufferSize 100 #define threadRc 55 pthread_key_t tlskey; void dataDestructor(void *parm); void cancelHandler(void *parm); void *threadfunc(void *parm); void level2(void); void level3(void); class A { public: A(char *label); ~A(); private: pthread_id_np_t tid; char buffer[bufferSize]; }; void dataDestructor(void *parm) { printf("In data destructor\n"); pthread_setspecific(tlskey, NULL); } void cancelHandler(void *parm) { printf("In cancellation cleanup handler\n"); } void *threadfunc(void *parm) { A object("start routine object"); level2(); return NULL; } void level2(void) { A object("Second level object"); level3(); } void level3(void) { int rc; struct timespec ts = {5, 0}; A object("Third level object"); pthread_setspecific(tlskey, &tlskey); pthread_cleanup_push(cancelHandler, NULL); printf("Thread blocked\n"); rc = pthread_delay_np(&ts); if (rc != 0) { printf("pthread_delay_np() - return code %d\n", rc); return; } printf("Calling pthread_exit()\n"); pthread_exit(__VOID(threadRc)); pthread_cleanup_pop(0); } int main(int argc, char **argv) { int rc=0; int i; pthread_t threadid; void *status; int fail=0; printf("Enter Testcase - %s\n", argv[0]); rc = pthread_key_create(&tlskey, dataDestructor); checkResults("pthread_key_create()\n", rc); printf("----------- Start pthread_cancel() example -------------\n"); printf("Create a thread\n"); rc = pthread_create(&threadid, NULL, threadfunc, NULL); checkResults("pthread_create()\n", rc); sleep(2); rc = pthread_cancel(threadid); checkResults("pthread_cancel()\n", rc); rc = pthread_join(threadid, &status); checkResults("pthread_join()\n", rc); if (status != PTHREAD_CANCELED) { printf("Canceled thread did not return the expected results\n"); fail = 1; } printf("----------- Start pthread_exit() example -------------\n"); printf("Create a thread\n"); rc = pthread_create(&threadid, NULL, threadfunc, NULL); checkResults("pthread_create()\n", rc); rc = pthread_join(threadid, &status); checkResults("pthread_join()\n", rc); if (__INT(status) != threadRc) { printf("pthread_exit() thread did not return the expected results\n"); fail = 1; } pthread_key_delete(tlskey); if (fail) { printf("At least one thread failed!\n"); exit(1); } printf("Main completed\n"); return 0; } A::A(char *label) { strncpy(buffer, label, bufferSize); pthread_t me; me = pthread_self(); pthread_getunique_np(&me, &tid); printf("`%s' instantiated in thread 0x%.8x %.8x\n", buffer, tid); } A::~A() { printf("`%s' destroyed in thread 0x%.8x %.8x\n", buffer, tid); }
Output:
Enter Testcase - QP0WTEST/TPCPP0 ----------- Start pthread_cancel() example ------------- Create a thread `start routine object' instantiated in thread 0x00000000 00000161 `Second level object' instantiated in thread 0x00000000 00000161 `Third level object' instantiated in thread 0x00000000 00000161 Thread blocked In cancellation cleanup handler In data destructor `Third level object' destroyed in thread 0x00000000 00000161 `Second level object' destroyed in thread 0x00000000 00000161 `start routine object' destroyed in thread 0x00000000 00000161 ----------- Start pthread_exit() example ------------- Create a thread `start routine object' instantiated in thread 0x00000000 00000162 `Second level object' instantiated in thread 0x00000000 00000162 `Third level object' instantiated in thread 0x00000000 00000162 Thread blocked Calling pthread_exit() In cancellation cleanup handler In data destructor `Third level object' destroyed in thread 0x00000000 00000162 `Second level object' destroyed in thread 0x00000000 00000162 `start routine object' destroyed in thread 0x00000000 00000162 Main completed
Top | Pthread APIs | APIs by category |