pthread_cleanup_push和pthread_cleanup_pop學習

pthread_cleanup_push:註冊線程退出時的處理程序,與進程的atexit函數類似,只是以壓棧的方式儲存。

pthread_cleanup_pop:調用已經壓棧的線程退出處理程序,當參數非零。

註冊的線程退出處理函數僅在以下三種情況下才會被調用:

1、調用pthread_exit退出線程時;

2、響應取消請求時;

3、用非零參數調用pthread_cleanup_pop函數。

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>

void cleanup(void *arg)
{
	printf("cleanup:%s\n",(char *)arg);
}

void* thr_fn1(void *arg)
{
	printf("thread 1 start\n");
	pthread_cleanup_push(cleanup,"thread 1 first handler");
	pthread_cleanup_push(cleanup,"thread 1 second handler");
	printf("thread 1 push complete\n");

	if(arg)
	{
		return (void *)1;
	}

	pthread_cleanup_pop(1);
	printf("here %d\n",__LINE__);

	pthread_cleanup_pop(2);
	return (void *)1;
}

void* thr_fn2(void *arg)
{
	printf("thread 2 start\n");
	pthread_cleanup_push(cleanup,"thread 2 first handler");
	pthread_cleanup_push(cleanup,"thread 2 second handler");
	printf("thread 2 push complete\n");

	if(arg)
	{
		pthread_exit((void *)2);
	}

	printf("thread 2 is %d\n",__LINE__);
	pthread_cleanup_pop(0);
	printf("thread 2 here is %d\n",__LINE__);
	pthread_cleanup_pop(0);

	return (void *)2;
}

int main()
{
	int err;
	pthread_t tid1,tid2;
	void *tret;

	err = pthread_create(&tid1,NULL,thr_fn1,(void *)1);
	if(0 != err)
	{
		printf("error:%s\n","cann't create thread 1");
	}

	err = pthread_create(&tid2,NULL,thr_fn2,(void *)2);
	if(0 != err)
	{
		printf("error:%s\n","cann't create thread 2");
	}
	
	err = pthread_join(tid1,&tret);
	if(0 != err)
	{
		printf("error:%s\n","cann't join with thread 1");
	}
	printf("thread 1 exit code %ld\n",(long)tret);

	err = pthread_join(tid2,&tret);
	if(0 != err)
	{
		printf("error:%s\n","cann't join with thread 2");
	}
	printf("thread 2 exit code %ld\n",(long)tret);

	exit(0);
}

注意點:

1、pthread_cleanup_push和pthread_cleanup_pop兩個函數必須成對出現,壓棧兩個就必須彈棧兩個,否則編譯會報錯,而且報的很莫名其妙;

2、調用順序與壓棧的時候恰好相反,如果壓棧時fun1 --> fun2;調用的順序就是fun2 --> fun1。

至於pthread_cleanup_pop的參數貌似只有零和非零的區分。因爲此時會調用壓棧的函數,而函數的參數是當初壓棧的時候就已經確定了,與pthread_cleanup_pop的參數毫無關係。



發佈了53 篇原創文章 · 獲贊 10 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章