日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【pthread_cancel函数:避免踩坑】

發(fā)布時間:2023/12/20 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【pthread_cancel函数:避免踩坑】 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • pthread_cancel()函數(shù)是什么?
  • 1、pthread_cancel() 函數(shù)生效,代碼演示:
  • 2、pthread_cancel() 函數(shù)不生效,代碼演示
  • 總結


pthread_cancel()函數(shù)是什么?

線程結束執(zhí)行的方式共有 3 種,分別是:
1.線程將指定函數(shù)體中的代碼執(zhí)行完后自行結束;
2.線程執(zhí)行過程中,遇到 pthread_exit() 函數(shù)結束執(zhí)行。
3.線程執(zhí)行過程中,被同一進程中的其它線程(包括主線程)強制終止;

  • 第一種方式:很容易理解,就是函數(shù)內(nèi)所有代碼執(zhí)行完畢后,線程主動結束。
  • 第二種方式:已經(jīng)在《pthread_exit()函數(shù)》一節(jié)中做了詳細的介紹。
  • 第 3 種方式:本節(jié)給大家重點介紹,多線程程序中,一條線程可以借助
    pthread_cancel() 函數(shù)向另一條線程發(fā)送“終止執(zhí)行”的信號(后續(xù)稱“Cancel”信號),從而令目標線程結束執(zhí)行。

pthread_cancel() 函數(shù)聲明在<pthread.h>頭文件中,語法格式如下:

int pthread_cancel(pthread_t tid); //向 tid 目標線程發(fā)送 Cancel 信號

如果 pthread_cancel() 函數(shù)成功地發(fā)送了 Cancel 信號,返回數(shù)字 0;反之如果發(fā)送失敗,函數(shù)返回值為非零數(shù)。對于因“未找到目標線程”導致的信號發(fā)送失敗,函數(shù)返回 ESRCH 宏(定義在<errno.h>頭文件中,該宏的值為整數(shù) 3)。

注意,pthread_cancel() 函數(shù)的功能僅僅是向目標線程發(fā)送 Cancel 信號,至于目標線程是否處理該信號以及何時結束執(zhí)行,由目標線程決定。

對于接收 Cancel 信號后結束執(zhí)行的目標線程,等同于該線程自己執(zhí)行如下語句:

pthread_exit(PTHREAD_CANCELED);

也就是說,當一個線程被強制終止執(zhí)行時,它會返回 PTHREAD_CANCELED 這個宏(定義在<pthread.h>頭文件中)。

1、pthread_cancel() 函數(shù)生效,代碼演示:

#include <stdio.h> #include <pthread.h> #include <unistd.h> // sleep() 函數(shù)//創(chuàng)建一個互斥量 pthread_mutex_t mutex;//線程執(zhí)行的函數(shù) void * thread_func1(void * arg) {printf("新建線程開始執(zhí)行.....\n");//加鎖pthread_mutex_lock(&mutex);printf("新建線程執(zhí)行中.....\n");sleep(10); //在系統(tǒng)調(diào)用sleep()時設置一個取消點(cancelpoint),線程將會從這里直接退出 //解鎖pthread_mutex_unlock(&mutex);printf("新建線程執(zhí)行完畢.....\n"); }int main() {pthread_t myThread;void * mess;int value;int res;//初始化互斥量pthread_mutex_init(&mutex, NULL);//創(chuàng)建 myThread 線程res = pthread_create(&myThread, NULL, thread_func1, NULL);if (res != 0) {printf("線程創(chuàng)建失敗\n");return 0;}sleep(1);//向 myThread 線程發(fā)送 Cancel 信號res = pthread_cancel(myThread);if (res != 0) {printf("終止 myThread 線程失敗\n");return 0;}//獲取已終止線程的返回值res = pthread_join(myThread, &mess);if (res != 0) {printf("等待線程失敗\n");return 0;}//如果線程被強制終止,其返回值為 PTHREAD_CANCELEDif (mess == PTHREAD_CANCELED) {printf("myThread 線程被強制終止\n");}else {printf("error\n");}//釋放互斥量資源pthread_mutex_destroy(&mutex);return 0; }

假設程序編寫在 pthread_cancel.c 文件中,執(zhí)行過程為:

[root@localhost ~]# gcc pthread_cancel.c -o thread -lpthread
[root@localhost ~]# ./thread
新建線程開始執(zhí)行…
新建線程執(zhí)行中…
myThread 線程被強制終止

*注意:thread_func1()函數(shù)內(nèi)加了互斥鎖,但是并沒有解鎖線程就直接退出了,這就導致了死鎖。這就是我想提醒大家使用 pthread_cancel()函數(shù)時需要重點關注的地方。

2、pthread_cancel() 函數(shù)不生效,代碼演示

#include <stdio.h> #include <pthread.h> #include <unistd.h> // sleep() 函數(shù)//創(chuàng)建一個互斥量 pthread_mutex_t mutex;//線程執(zhí)行的函數(shù) void * thread_func2(void * arg) {printf("新建線程開始執(zhí)行.....\n");//加鎖pthread_mutex_lock(&mutex);printf("新建線程執(zhí)行中.....\n");//sleep(10); //函數(shù)內(nèi)沒有系統(tǒng)調(diào)用,故沒有設置一個取消點(cancelpoint),線程將不會退出而是繼續(xù)往下執(zhí)行代碼 //解鎖pthread_mutex_unlock(&mutex);printf("新建線程執(zhí)行完畢.....\n"); }int main() {pthread_t myThread;void * mess;int value;int res;//初始化互斥量pthread_mutex_init(&mutex, NULL);//創(chuàng)建 myThread 線程res = pthread_create(&myThread, NULL, thread_func2, NULL);if (res != 0) {printf("線程創(chuàng)建失敗\n");return 0;}sleep(1);//向 myThread 線程發(fā)送 Cancel 信號res = pthread_cancel(myThread);if (res != 0) {printf("終止 myThread 線程失敗\n");return 0;}//獲取已終止線程的返回值res = pthread_join(myThread, &mess);if (res != 0) {printf("等待線程失敗\n");return 0;}//如果線程被強制終止,其返回值為 PTHREAD_CANCELEDif (mess == PTHREAD_CANCELED) {printf("myThread 線程被強制終止\n");}else {printf("error\n");}//釋放互斥量資源pthread_mutex_destroy(&mutex);return 0; }

假設程序編寫在 pthread_cancel.c 文件中,執(zhí)行過程為:

[root@localhost ~]# gcc pthread_cancel.c -o thread -lpthread
[root@localhost ~]# ./thread
新建線程開始執(zhí)行…
新建線程執(zhí)行中…
新建線程執(zhí)行完畢…
終止 myThread 線程失敗

*注意:thread_func2()函數(shù)沒有按照預想的方式直接退出。


總結

大家發(fā)現(xiàn)沒?
1.pthread_cancel()函數(shù)不是直接使得目標線程退出的,而是在系統(tǒng)調(diào)用中設置一個取消點(cancelpoint),當有系統(tǒng)調(diào)用函數(shù)時就會檢查是否設置了這個cancelpoint,如果設置了就立即退出線程,否則不退出。
2.sleep()函數(shù)屬于系統(tǒng)調(diào)用,當使用了sleep()時系統(tǒng)就會檢查cancelpoint,這時就會讓目標線程直接退出。但是在thread_func2()函數(shù)中沒有系統(tǒng)調(diào)用函數(shù),而是我們自己編寫的C代碼,所以不會設置這個cancelpoint,故不會退出線程。

感謝以下博主提供思路:
1.pthread_cancel()函數(shù):終止線程執(zhí)行
2.線程退出函數(shù)pthread_cancel() 采坑點

總結

以上是生活随笔為你收集整理的【pthread_cancel函数:避免踩坑】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。