線程分離

pthread_detach函數

實現線程分離

?????? int pthread_detach(pthread_t thread);????? 成功:0;失敗:錯誤號

?????? 線程分離狀態:指定該狀態,線程主動與主控線程斷開關系。線程結束后,其退出狀態不由其他線程獲取,而直接自己自動釋放。網絡、多線程服務器常用。

?????? 進程若有該機制,將不會產生僵尸進程。僵尸進程的產生主要由于進程死后,大部分資源被釋放,一點殘留資源仍存于系統中,導致內核認為該進程仍存在。

?????? 也可使用 pthread_create函數參2(線程屬性)來設置線程分離。

【練習】:使用pthread_detach函數實現線程分離??????????????????????????????????????????????????????? ????????????? 【pthrd_detach.c】

一般情況下,線程終止后,其終止狀態一直保留到其它線程調用pthread_join獲取它的狀態為止。但是線程也可以被置為detach狀態,這樣的線程一旦終止就立刻回收它占用的所有資源,而不保留終止狀態。不能對一個已經處于detach狀態的線程調用pthread_join,這樣的調用將返回EINVAL錯誤。也就是說,如果已經對一個線程調用了pthread_detach就不能再調用pthread_join了。

/***
detach.c
***/
#include<unistd.h>
#include<string.h>
#include<pthread.h>
#include<stdio.h>void *tfn(void *arg)
{int n = 3;while(n--){printf("thread count %d\n",n);sleep(1);}pthread_exit((void*)1);
}int main()
{pthread_t tid;void* tret;int err;pthread_attr_t attr;pthread_attr_init(&attr);pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);pthread_create(&tid,&attr,tfn,NULL);while(1){err = pthread_join(tid,&tret);printf("------------------- err = %d\n",err);if(0 != err){fprintf(stderr,"thread_join error : %s\n",strerror(err));}else{fprintf(stderr,"thread exit code %d\n",(int)tret);}sleep(1);}return 0;
}

運行結果:

ubuntu1604@ubuntu:~/wangqinghe/linux/20190819$ ./detach

------------------- err = 22

thread_join error : Invalid argument

thread count 2

------------------- err = 22

thread_join error : Invalid argument

thread count 1

------------------- err = 22

thread_join error : Invalid argument

thread count 0

------------------- err = 22

thread_join error : Invalid argument

------------------- err = 22

thread_join error : Invalid argument

------------------- err = 22

thread_join error : Invalid argument

------------------- err = 22

thread_join error : Invalid argument

^C

pthread_cancel函數

殺死(取消)線程????????????????? 其作用,對應進程中 kill() 函數。

?????? int pthread_cancel(pthread_t thread); 成功:0;失敗:錯誤號

?????? 【注意】:線程的取消并不是實時的,而有一定的延時。需要等待線程到達某個取消點(檢查點)。

?????? 類似于玩游戲存檔,必須到達指定的場所(存檔點,如:客棧、倉庫、城里等)才能存儲進度。殺死線程也不是立刻就能完成,必須要到達取消點。

?????? 取消點:是線程檢查是否被取消,并按請求進行動作的一個位置。通常是一些系統調用creat,open,pause,close,read,write..... 執行命令man 7 pthreads可以查看具備這些取消點的系統調用列表。也可參閱 APUE.12.7 取消選項小節。

可粗略認為一個系統調用(進入內核)即為一個取消點。如線程中沒有取消點,可以通過調用pthreestcancel函數自行設置一個取消點。

被取消的線程,?? 退出值定義在Linux的pthread庫中。常數PTHREAD_CANCELED的值是-1。可在頭文件pthread.h中找到它的定義:#define PTHREAD_CANCELED ((void *) -1)。因此當我們對一個已經被取消的線程使用pthread_join回收時,得到的返回值為-1。

【練習】:終止線程的三種方法。注意“取消點”的概念。??????????????????????????????????????????????? ????????????? 【pthrd_endof3.c】

終止線程方式

總結:終止某個線程而不終止整個進程,有三種方法:

  1. 從線程主函數return。這種方法對主控線程不適用,從main函數return相當于調用exit。
  2. 一個線程可以調用pthread_cancel終止同一進程中的另一個線程。
  3. 線程可以調用pthread_exit終止自己
/***
pthread_endof3.c
***/#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;
}

ubuntu1604@ubuntu:~/wangqinghe/linux/20190819$ ./pthread_endof3

thread 1 returning

thread 1 exit code = 111

?

thread 2 exiting

thread 2 exit code = 222

?

thread 3 exit code = -1

?

轉載于:https://www.cnblogs.com/wanghao-boke/p/11389738.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/384862.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/384862.shtml
英文地址,請注明出處:http://en.pswp.cn/news/384862.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

線程知識點

控制原語對比 進程 線程 fork pthread_create exit pthread_exit wait pthread_join kill pthread_cancel getpid pthread_self 命名空間 線程屬性 本節作為指引性介紹&…

讀寫鎖

讀寫鎖 與互斥量類似&#xff0c;但讀寫鎖允許更高的并行性。其特性為&#xff1a;寫獨占&#xff0c;讀共享。 讀寫鎖狀態&#xff1a; 一把讀寫鎖具備三種狀態&#xff1a; 1. 讀模式下加鎖狀態 (讀鎖) 2. 寫模式下加鎖狀態 (寫鎖) 3. 不加鎖狀態 讀寫鎖特性&#xff1a; 讀…

條件變量

條件變量&#xff1a; 條件變量本身不是鎖&#xff01;但它也可以造成線程阻塞。通常與互斥鎖配合使用。給多線程提供一個會合的場所。 主要應用函數&#xff1a; pthread_cond_init函數 pthread_cond_destroy函數 pthread_cond_wait函數 pthread_cond_timedwait函數 pthread_c…

文件鎖

借助 fcntl函數來實現鎖機制。 操作文件的進程沒有獲得鎖時&#xff0c;可以打開&#xff0c;但無法執行read、write操作。 fcntl函數&#xff1a; 獲取、設置文件訪問控制屬性。 int fcntl(int fd, int cmd, ... /* arg */ ); 參2&#xff1a; F_SETLK (struct flock *) 設置…

進程間同步

互斥量mutex 進程間也可以使用互斥鎖&#xff0c;來達到同步的目的。但應在pthread_mutex_init初始化之前&#xff0c;修改其屬性為進程間共享。mutex的屬性修改函數主要有以下幾個。 主要應用函數&#xff1a; pthread_mutexattr_t mattr 類型&#xff1a; 用于定義…

Python3字符串

字符串是Python中最常用的數據類型&#xff0c;可以使用單引號或雙引號來創建字符串 創建字符串很簡單&#xff0c;為變量分配一個值即可。 val1 ‘hello world’ var2 “Runoob” Python訪問字符串的值 Python不支持單字符類型&#xff0c;單字符在Python中也是作為 一個字符…

服務器客戶端編程

server 下面通過最簡單的客戶端/服務器程序的實例來學習socket API。 server.c的作用是從客戶端讀字符&#xff0c;然后將每個字符轉換為大寫并回送給客戶端。 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #incl…

Python3元組

Python的元組與列表相似&#xff0c;不同之處在于元組的元素不能修改 元組使用小括號&#xff0c;列表使用方括號 元組創建很簡單&#xff0c;只需要在括號中添加元素&#xff0c;并使用逗號隔開即可。 創建空元組 tup1 (); tup2 (1,) 元組只包含一個元素時&#xff0c;需要在…

Python3字典

字典是另一種可變容器模型&#xff0c;可存儲任意類型的對象。 字典的每個鍵值(key>value)對用冒號分隔&#xff0c;每個對之間用逗號分隔&#xff0c;整個字典包括在花括號里&#xff0c;格式如下 d {key1 : value,key2 : value2} 鍵必須是唯一&#xff0c;但值則不必。 值…

線程回收

pthread_join函數 阻塞等待線程退出&#xff0c;獲取線程退出狀態 其作用&#xff0c;對應進程中 waitpid() 函數。 int pthread_join(pthread_t thread, void **retval); 成功&#xff1a;0&#xff1b;失敗&#xff1a;錯誤號 參數&#xff1a;thread&#xff1a;線…

Python3數字

Python3數字數據類型用于存儲數值。 數據類型是不允許改變的&#xff0c;這就意味著&#xff0c;如果改變數字數據類型的值&#xff0c;將重新分配內存空間。 Python支持三種不同不同的數值類型&#xff1a; 整型&#xff08;int&#xff09;&#xff1a;通常是被稱為整型或整數…

多進程服務器

注意&#xff1a;包含了“wrap.c” 和“wrap.h”文件在上篇博客中 /*** server.c ***/ #include<stdio.h> #include<string.h> #include<netinet/in.h> #include<arpa/inet.h> #include<signal.h> #include<sys/wait.h> #include<ctype…

服務器之select

select select能監聽的文件描述符個數受限于FD_SETSIZE,一般為1024&#xff0c;單純改變進程打開的文件描述符個數并不能改變select監聽文件個數解決1024以下客戶端時使用select是很合適的&#xff0c;但如果鏈接客戶端過多&#xff0c;select采用的是輪詢模型&#xff0c;會大…

服務器之poll

poll服務器方法采用將監聽端口用數組存放起來&#xff0c;這樣就不需要輪詢的監聽整個文件描述符了 #include <poll.h> int poll(struct pollfd *fds, nfds_t nfds, int timeout);struct pollfd {int fd; /* 文件描述符 */short events; /* 監控的事件 */short revents; …

Mysql數據庫簡單使用(二)

Mysql導入.sql文件 進入數據庫&#xff08;要導入的數據庫&#xff09;數據庫中有要導入.sql文件名的數據庫&#xff0c;沒有則新建。source 路徑文件名souce /home/robot/csql.sql 數據庫文件.sql文件放在/home/robot目錄下 按照時間刪除數據庫數據 DELETE FROM 表名 WHERE 時…

Python3集合

集合&#xff08;set&#xff09;是一個無序的不重復元素序列。 可以使用大括號{ } 或set&#xff08;&#xff09;函數來創建集合&#xff0c;注意&#xff1a;創建一個空集合必須用set(),{ }是用來創建一個空字典的。 創建格式&#xff1a; param {value01,value02,…} set(…

Python3條件判斷

if語句&#xff1a; Python中if語句的一般形式如下&#xff1a; if condition_1:statement_block_1 elif condition_2:statement_block_2 else:statement_block_3 if語句關鍵詞&#xff1a; if – elif – else 注意&#xff1a; 每個條件后面要使用冒號:使用縮進來劃分語句塊&…

Python3循環

Python中while語句的一般形式&#xff1a; while 判斷條件: 語句 同樣需要注意冒號和縮進&#xff0c;另外在Python中沒有do…while循環 下面的實例計算1到100總和 ##calc.py n 100sum 0 counter 1 while counter < n:sum sum countercounter 1print("total from…

Python3迭代器和生成器

迭代器 迭代是Python最強大的功能之一&#xff0c;是訪問元素集合的一種方法。 迭代器是一個可以記住遍歷的位置的對象。 迭代器對象從集合的第一個元素開始訪問&#xff0c;直到所有的元素被訪問完結束&#xff0c;迭代器只能向前不會后退。 迭代器有兩個基本方法&#xff0c;…

Pythton3實例

計算1-100之和 #add.py n 0 sum 0 for n in range(0,101):sum n print(sum) 實現99乘法法則 #mul.py i 1 while i < 9:j 1while j < i:mut j*iprint("%d * %d %d"%(j,i,mut),end" ")j 1print(" ")i 1 運算結果: robotubuntu:~/wa…