1. 程式人生 > 其它 >09LinuxC執行緒學習之pthread_cancel函式及其案例

09LinuxC執行緒學習之pthread_cancel函式及其案例

技術標籤:多執行緒c語言

1 pthread_cancel函式

int pthread_cancel(pthread_t thread);	
/*
	功能:殺死(取消)執行緒,其作用,對應程序中kill()函式。
	成功:0;失敗:錯誤號。
	參1:要殺死執行緒的tid。
*/

2 pthread_cancel函式案例

2.1 案例1

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

void *tfn(void *arg){
	
	while
(1){ printf("thread pid=%d, tid=%lu\n", getpid(), pthread_self()); sleep(1); ) return NULL; } int main(int argc, char *argv[]){ pthread_t tid; tid[i] = -1; int ret = pthread_create(&tid[i], NULL, tfn, NULL); if(ret != 0){ fprintf(stderr, "pthread_create failed:%s\n"
, strerror(ret)); exit(1); } printf("main pid=%d, tid=%lu\n", getpid(), pthread_self()); sleep(5); pthread_cancel(tid);//終止執行緒,但需要一個執行的CPU分片 if(ret != 0){ fprintf(stderr, "pthread_create failed:%s\n", strerror(ret)); exit(1); } while(1); return 0; }

上面程式碼結果,當我們每一秒在子執行緒列印,5秒後主執行緒呼叫cancel函式成功殺死子執行緒。

在這裡插入圖片描述

2.2 案例2

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


void *tfn1(void *arg)
{
	printf("thread 1 returning\n");

	return (void *)111; 
}

void *tfn2(void *arg)
{
	printf("thread 2 exiting\n");
	pthread_exit((void *)222);
}

void *tfn3(void *arg)
{
	while (1) {
		//printf("thread 3: I'm going to die in 3 seconds ...\n");
		//sleep(1);
		//pthread_testcancel();	//自己新增取消點*/
	}

    return (void *)666;
}

int main(void)
{
	pthread_t tid;
	void *tret = NULL;

	pthread_create(&tid, NULL, tfn1, NULL);
	pthread_join(tid, &tret);
	printf("thread 1 exit code = %d\n\n", (int)tret);

	pthread_create(&tid, NULL, tfn2, NULL);
	pthread_join(tid, &tret);
	printf("thread 2 exit code = %d\n\n", (int)tret);

	pthread_create(&tid, NULL, tfn3, NULL);
	sleep(3);
    pthread_cancel(tid);
	pthread_join(tid, &tret);
	printf("thread 3 exit code = %d\n", (int)tret);

	return 0;
}


結果分析,上面程式碼是第三個執行緒在主執行緒結束後將被殺死,但是圖中並未殺死打印出:thread 3 exit codexxx,而是子執行緒繼續卡死執行while(1)迴圈。這是為什麼呢?這是因為呼叫pthread_cancel殺死子執行緒必須有系統呼叫函式,例如新增sleep()或者其它,注意if,switch這些不是系統呼叫,所以也不會給契機pthread_cancel殺死子執行緒。最好的方法是呼叫pthread_testcancel,它內部作了系統呼叫的處理。
在這裡插入圖片描述

3 總結pthread_cancel

  • 1)pthread_cancel可以殺死子執行緒,但必須需要一個契機,這個契機就是系統呼叫。一般方法是呼叫pthread_testcancel提供契機處理。並且join再回收該被殺死的子執行緒的返回值為pthread.h中的巨集#define PTHREAD_CANCELED ((void *) -1)。