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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

线程的控制(创建、等待、终止)、分离线程

發布時間:2023/12/20 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 线程的控制(创建、等待、终止)、分离线程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、線程控制


1、線程:線程是資源調度的基本單位,線程是進程內部的一個執行流,在進程的地址空間內運行。在Linux 下沒有真正意義上的線程,線程是用進程模擬的,又被稱為輕量級進程。

? ? ? ? 2、由于同?一進程的多個線程共享同?一地址空間。因此Text Segment、Data Segment都是共享的,除此之外,各線程還共享以下進程資源和環境:

1). ?文件描述符表;

2). 每種信號的處理?方式(SIG_IGN、SIG_DFL或者?自定義的信號處理函數);

3). 當前?工作?目錄;

4). ?用戶id和組id;

但有些資源是每個線程各有一份的:

1).線程id

2). 上下?文,包括各種寄存器的值、程序計數器和棧指針

3). 棧空間

4). errno變量

5). 信號屏蔽字

6). 調度優先級


3、線程創建:

? ? ??函數原型:int pthread_create(pthread_t?thread, const pthread_attr_t *attr, void?(start_routine) (void?), void *arg);?

創建成功:返回0 ;創建失敗:返回錯誤碼,可將錯誤碼通過strerror()轉換為字符串描述。?

參數1:線程id地址(只在用戶區有效)。?

參數2:線程屬性,一般設置為NULL。?

參數3:函數指針,指向線程函數。?

參數4:線程函數的參數。


?? ? ?

創建結果:?

?? ? ? ? ? ? ? ??


3、終?止線程

????? 如果需要只終?止某個線程?而不終?止整個進程,可以有三種?方法:

? ? ? ?1. 從線程函數return。這種?方法對主線程不適?用,從main函數return相當于調?用exit。

? ? ? ?2. ?一個線程可以調?用pthread_cancel終?止同?一進程中的另?一個線程?用pthread_cancel終?止?一個線程分同步和異步兩種情況

? ? ? ?3. 線程可以調?用pthread_exit終?止?自?己。

4、線程等待

? ? 返回值:成功返回0,失敗返回錯誤號
? ? 調?用該函數的線程將掛起等待,直到id為thread的線程終?止。thread線程以不同的?方法終?止,通過pthread_join得到的終?止狀態是不同的,總結如下:
? ? 1. 如果thread線程通過return返回,value_ptr所指向的單元?里存放的是thread線程函數的返回值。
? ? 2. 如果thread線程被別的線程調?用pthread_cancel異常終掉,value_ptr所指向的單元?里存放的是常數PTHREAD_CANCELED。
? ? 3. 如果thread線程是?自?己調?用pthread_exit終?止的,value_ptr所指向的單元存放的是傳給pthread_exit的參數。 如果對thread線程的終?止狀態不感興趣,可以 ? ? ?傳NULL給value_ptr參數

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


void* thread1(void* arg)
{


? ? printf("new thread1\n");
? ? return (void*)123;
}
void* thread2(void* arg)
{
? ? while(1)
? ? {
? ? ? ? printf("new thread2\n");
? ? ? ? sleep(1);
? ? ? ? pthread_exit((void*)456);
? ? }
? ??
}
void* thread3(void* arg)//被其他線程cancel
{
? ? while(1)
? ? {
? ? ? ? printf("new thread3\n");
? ? ? ? sleep(1);
? ? }
? ? return NULL;
}


int main()
{
? ? pthread_t tid1,tid2,tid3,tid4;
? ? void* val = NULL;
? ? pthread_create(&tid1,NULL,thread1,NULL);
? ? pthread_create(&tid2,NULL,thread2,NULL);
? ? pthread_create(&tid3,NULL,thread3,NULL);
? ? pthread_create(&tid4,NULL,thread4,NULL);
? ??
? ? pthread_join(tid1,&val);
? ? printf("thread1 is quit,thread1 id is %lu, exit code:%d\n",tid1,(int)val);
? ? pthread_join(tid2,&val);
? ? printf("thread2 is quit,thread2 id is %lu, exit code:%d\n",tid2,(int)val);


? ? pthread_cancel(tid3);
? ? pthread_join(tid3,&val);
? ? printf("thread3 is quit,thread3 id is %lu, exit code:%d\n",tid3,(int)val);


? ? return 0;
}?


運行結果:



注:

可見在Linux的pthread庫中常數PTHREAD_CANCELED的值是-1。可以在頭?文件pthread.h中找到它的定義。

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



二、分離線程


在任何?一個時間點上,線程是可結合的(joinable)或者是分離的(detached)。一個可結合的線程能夠被其他線程收回其資源和殺死。在被其他線程回收之前,

它的存儲器資源(例如棧)是不釋放的。相反,?一個分離的線程是不能被其他線程回收或殺死的,它的存儲器 資源在它終?止時由系統?自動釋放。


1、默認情況下,線程被創建成可結合的。為了避免存儲器泄漏,每個可結合線程都應該要么被顯?示地回收,即調?用pthread_join;要么通過調?用pthread_detach

函數被分離。如果?一個可結合線程結束運?行但沒有被join,則它的狀態類似于進程中的Zombie Process,即還有?一部分資源沒有被回收,所以創建線程者應該調

pthread_join來等待線程運?行結束,并可得到線程的退出代碼,回收其資源。

2、?由于調?用pthread_join后,如果該線程沒有運?行結束,調?用者會被阻塞,在有些情況下我們并不希望如此。例如,在Web服務器中當主線程為每個新來的連接

請求創建?一個?子線程進?行處理的時候,主線程并不希望因為調?用pthread_join?而阻塞(因為還要繼續處理之后到來的連接請求),這時可以在?子線程中加入

代碼?pthread_detach(pthread_self())

或者?父線程調?用pthread_detach(thread_id)(?非阻塞,可?立即返回)

這將該?子線程的狀態設置為分離的(detached),如此一來,該線程運?行結束后會?自動釋放所有資源。


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


void* thread(void *_arg)
{
? ? //pthread_detach(pthread_self());//線程自已設置自已的可分離屬性
printf("new thread is run...\n");
? ? return (void*)1;
}


int main()
{
? ? pthread_t tid;
? ? int ret = pthread_create(&tid,NULL,thread,NULL);
? ? if(ret != 0)
? ? {
? ? ? ? printf("thread create failed,error code:%s\n",strerror(ret));
return ret;
? ? }
? ? sleep(1);
? ? pthread_detach(tid);//將子線程屬性設置為分離(非阻塞,可立即返回)
? ? void* val = NULL;
? ? if((pthread_join(tid, &val) != 0))
? ? {
? ? ? ? printf("thread wait failed\n");
ret = 1;
}
? ? else
? ? {
? ? ? ? printf("thread id : %u ,exit code : %d\n",tid, (int)val);
ret = 0;?
? ? }
? ? return ret;
}


運行結果:



? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?




總結

以上是生活随笔為你收集整理的线程的控制(创建、等待、终止)、分离线程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。