版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、第4章 線程管理與控制4.1 線程概念簡(jiǎn)介每個(gè)進(jìn)程都擁有自己的數(shù)據(jù)段、代碼段和堆棧段,這就造成了進(jìn)程在進(jìn)行切換等操作時(shí)都需要有比較復(fù)雜的上下文切換等動(dòng)作。為了進(jìn)一步減少處理機(jī)的空轉(zhuǎn)時(shí)間,支持多處理器以及減少上下文切換開(kāi)銷(xiāo),進(jìn)程在演化中出現(xiàn)了另一個(gè)概念線程。它是進(jìn)程內(nèi)獨(dú)立的一條運(yùn)行路線,處理器調(diào)度的最小單元,也可以稱(chēng)為輕量級(jí)進(jìn)程。線程可以對(duì)進(jìn)程的內(nèi)存空間和資源進(jìn)行訪問(wèn),并與同一進(jìn)程中的其他線程共享。因此,線程的上下文切換的開(kāi)銷(xiāo)比創(chuàng)建進(jìn)程小很多。同進(jìn)程一樣,線程也將相關(guān)的執(zhí)行狀態(tài)和存儲(chǔ)變量放在線程控制塊(TCB)內(nèi)。一個(gè)進(jìn)程可以有多個(gè)線程,也就是有多個(gè)線程控制塊及堆棧寄存器,但卻共享一個(gè)用戶地址空
2、間。要注意的是,由于線程共享了進(jìn)程的資源和地址空間,因此,任何線程對(duì)系統(tǒng)資源的操作都會(huì)給其他線程帶來(lái)影響。由此可知,多線程中的同步是非常重要的問(wèn)題。在多線程系統(tǒng)中,進(jìn)程與進(jìn)程的關(guān)系如圖所示。進(jìn)程與線程關(guān)系 4.2 Linux多線程編程API與實(shí)驗(yàn)任務(wù)4.3.1 Linux多線程編程API 創(chuàng)建線程pthread_create()函數(shù)實(shí)際上就是確定調(diào)用該線程函數(shù)的入口點(diǎn),在線程創(chuàng)建以后,就開(kāi)始運(yùn)行相關(guān)的線程函數(shù),在該函數(shù)運(yùn)行完之后,該線程也就退出了,這也是線程退出一種方法。另一種退出線程的方法是使用函數(shù)pthread_exit(),這是線程的主動(dòng)行為。這里要注意的是,在使用線程函數(shù)時(shí),不能隨意使
3、用exit()退出函數(shù)進(jìn)行出錯(cuò)處理,由于exit()的作用是使調(diào)用進(jìn)程終止,往往一個(gè)進(jìn)程包含多個(gè)線程,因此,在使用exit()之后,該進(jìn)程中的所有線程都終止了。因此,在線程中就可以使用pthread_exit()來(lái)代替進(jìn)程中的exit()。由于一個(gè)進(jìn)程中的多個(gè)線程是共享數(shù)據(jù)段的,因此通常在線程退出之后,退出線程所占用的資源并不會(huì)隨著線程的終止而得到釋放。正如進(jìn)程之間可以用wait()系統(tǒng)調(diào)用來(lái)同步終止并釋放資源一樣,線程之間也有類(lèi)似機(jī)制,那就是pthread_join()函數(shù)。pthread_join()可以用于將當(dāng)前線程掛起來(lái)等待線程的結(jié)束。這個(gè)函數(shù)是一個(gè)線程阻塞的函數(shù),調(diào)用它的函數(shù)將一直等
4、待到被等待的線程結(jié)束為止,當(dāng)函數(shù)返回時(shí),被等待線程的資源就被收回。(1)創(chuàng)建線程函數(shù)pthread_create()功能:創(chuàng)建線程和啟動(dòng)線程,與進(jìn)程管理函數(shù)fork()的功能相似。pthread_create()函數(shù)語(yǔ)法要點(diǎn)所需頭文件#include <pthread.h>函數(shù)原型int pthread_create (pthread_t *thread, pthread_attr_t *attr,void *(*start_routine)(void *), void *arg)函數(shù)傳入值thread:線程標(biāo)識(shí)符attr:線程屬性設(shè)置(其具體設(shè)置參見(jiàn)9.2.3小節(jié)),通常取為NU
5、LLstart_routine:線程函數(shù)的起始地址,是一個(gè)以指向void的指針作為參數(shù)和返回值的函數(shù)指針arg:傳遞給start_routine的參數(shù)函數(shù)返回值成功:0出錯(cuò):返回錯(cuò)誤碼(2) 線程退出函數(shù)pthread_exit()pthread_exit()函數(shù)語(yǔ)法要點(diǎn)所需頭文件#include <pthread.h>函數(shù)原型void pthread_exit(void *retval)函數(shù)傳入值retval:線程結(jié)束時(shí)的返回值,可由其他函數(shù)如pthread_join()來(lái)獲取(3) 等待線程結(jié)束函數(shù)pthread_join()等待線程結(jié)束,讀取線程的返回結(jié)果。pthread_j
6、oin()函數(shù)語(yǔ)法要點(diǎn)所需頭文件#include <pthread.h>函數(shù)原型int pthread_join (pthread_t th, void *thread_return)函數(shù)傳入值th:等待線程的標(biāo)識(shí)符thread_return:用戶定義的指針,用來(lái)存儲(chǔ)被等待線程結(jié)束時(shí)的返回值(不為NULL時(shí))函數(shù)返回值成功:0出錯(cuò):返回錯(cuò)誤碼(4) 線程取消函數(shù)pthread_cancel()pthread_cancel()函數(shù)語(yǔ)法要點(diǎn)所需頭文件#include <pthread.h>函數(shù)原型int pthread_cancel(pthread_t th)函數(shù)傳入值th
7、:要取消的線程的標(biāo)識(shí)符函數(shù)返回值成功:0出錯(cuò):返回錯(cuò)誤碼4.3.3 Linux多線程同步API1. 線程同步信號(hào)量及系統(tǒng)調(diào)用POSIX的線程同步信號(hào)量定義了3個(gè)函數(shù):(1) 信號(hào)量初始化函數(shù)說(shuō)明:#include <semaphore.h>int sem_init(sem_t *sem,int pshared,unsigned value);參數(shù)說(shuō)明:sem: 指向信號(hào)量變量的指針,*sem是定義好的信號(hào)量。pshared: 為0表示進(jìn)程局部信號(hào)量,通常為0value: 信號(hào)量初始值,為1時(shí)是二值信號(hào)量返回值:0:執(zhí)行成功,非0執(zhí)行失敗(2) 信號(hào)量加1原子操作int sem_po
8、st(sem_t *sem);說(shuō)明:類(lèi)似于進(jìn)程的V操作。(3) 信號(hào)量減1原子操作int sem_wait(sem_t *sem)說(shuō)明:在信線程號(hào)量值為0時(shí)執(zhí)行該操作使線程進(jìn)入等待狀態(tài),直到另一個(gè)線程執(zhí)行加1原子操作為止。類(lèi)似于進(jìn)程的P操作。2. 線程互斥量及系統(tǒng)調(diào)用互斥量可在多線程程序中作為臨界區(qū)互斥訪問(wèn)手段。操作互斥量的基本函數(shù)有:(1) 初始化函數(shù)函數(shù)說(shuō)明:#include <semaphore.h>int phread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);參數(shù)說(shuō)明:
9、mutex: 定義好的互斥量指針mutexattr:互斥量屬性,通??梢詾镹ULL(2) 加鎖操作int pthread_mutex_lock(pthread_mutex_t *mutex);(3) 開(kāi)鎖操作int pthread_mutex_unlock(pthread_mutex_t *mutex);(4) 互斥量撤銷(xiāo)操作int pthread_mutex_destroy(pthread_mutex_t *mutex);4.3.4 Linux多線程同步實(shí)驗(yàn)任務(wù)1. 用互斥量實(shí)現(xiàn)對(duì)4.3.2中多線程并發(fā)程序中共享變量的互斥訪問(wèn)。lin-thread-4.c:#include <stdi
10、o.h>#include <pthread.h>#include <unistd.h>static int a10000;static sum1,sum2,sum, p;pthread_mutex_t mutex; /互斥量,用于共享變量訪問(wèn)void *thread1(void *arg) int i;sum2=0;for(; ;) pthread_mutex_lock (&mutex);if (p<10000) sum2=sum2+ap;usleep(1);p+;pthread_mutex_unlock(&mutex);else pthre
11、ad_mutex_unlock(&mutex); break; pthread_exit(void*) sum2);int main(int argc,char* argv) pthread_t tidp; int error,i;int res;int thread_result;pthread_mutex_init (&mutex,NULL); /線程互斥量初始化為p=0; for (i=0; i<10000; i+) ai=i; error = pthread_create(&tidp,NULL, thread1,NULL); if(error != 0)
12、printf("thread is not created.n"); return -1; sum1=0;for(; ;) pthread_mutex_lock (&mutex);if (p<10000) sum1=sum1+ap;usleep(1);p+;pthread_mutex_unlock(&mutex);else pthread_mutex_unlock(&mutex); break; pthread_join(tidp,&thread_result); sum=sum1+sum2; printf("the sum
13、of array10000 is %dn",sum);printf("the part sum of thread1 get is %dn", thread_result); return 0;$ gcc lin-thread-4.c -lpthread -o lin-thread-4$ ./lin-thread-42. 分析、調(diào)試和執(zhí)行一個(gè)多線程示例程序lin-thread-5.c該程序創(chuàng)建兩個(gè)線程,一個(gè)線程負(fù)責(zé)讀入鍵盤(pán)輸入的文本,另一個(gè)線程負(fù)責(zé)統(tǒng)計(jì)和顯示輸入的字符個(gè)數(shù),文本輸入以“end”表示輸入結(jié)束。程序在主線程中對(duì)結(jié)束的兩個(gè)線程進(jìn)行歸并。lin-threa
14、d-5.c#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <pthread.h>#include <semaphore.h>void *input_text(void *arg);void *count_text(void *arg);void *stat_text(void *arg);sem_t bin_sem;
15、60;/信號(hào)量,用于線程同步#define WORK_SIZE 1024char work_areaWORK_SIZE;int main() int res; /線程函數(shù)執(zhí)行的返回值 pthread_t input_thread,stat_thread; /線程標(biāo)識(shí)符變量
16、; void *thread_result; /線程執(zhí)行的返回值 res = sem_init(&bin_sem,0,0); /線程同步信號(hào)量初始化為0 if (res!=0) &
17、#160; perror("Semaphore init failed"); exit(EXIT_FAILURE); res = pthread_create(&input_thread,NULL, inp
18、ut_text,NULL); if (res!=0) perror("Input Thread init failed"); exit(EXIT_FAILURE);
19、; res = pthread_create(&stat_thread,NULL, stat_text,NULL); if (res!=0) perror("Stat Thread init
20、 failed"); exit(EXIT_FAILURE); printf("Waiting for thread to finishn");
21、res = pthread_join(input_thread,&thread_result); res = pthread_join(stat_thread,&thread_result); printf("Threads joinedn"); sem_destroy(&bin_sem); exit(EXIT_SUCCESS); void *input_text(void *arg) printf("Input some text. Enter end to finishn"); while(strncmp("end",work_area,3)!=0)
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度物聯(lián)網(wǎng)解決方案代理授權(quán)銷(xiāo)售合同范本4篇
- 2024銅門(mén)制安工程招投標(biāo)合同
- 2025年度校園文化節(jié)影視展贊助合同3篇
- 2025年歷史建筑圍墻修繕施工合同4篇
- 2025年度廚房設(shè)備翻新與性能提升合同3篇
- 2025年度智能大廈腳手架設(shè)計(jì)與施工一體化合同4篇
- 2025年cfg樁基施工綠色施工技術(shù)交流與合作合同3篇
- 2024銷(xiāo)售委托合同范本
- 2025年度出租車(chē)駕駛員權(quán)益保障合同3篇
- 2025年度新型冷鏈物流承包運(yùn)輸合同4篇
- 非誠(chéng)不找小品臺(tái)詞
- 2024年3月江蘇省考公務(wù)員面試題(B類(lèi))及參考答案
- 患者信息保密法律法規(guī)解讀
- 老年人護(hù)理風(fēng)險(xiǎn)防控PPT
- 充電樁采購(gòu)安裝投標(biāo)方案(技術(shù)方案)
- 醫(yī)院科室考勤表
- 鍍膜員工述職報(bào)告
- 春節(jié)期間化工企業(yè)安全生產(chǎn)注意安全生產(chǎn)
- 保險(xiǎn)行業(yè)加強(qiáng)清廉文化建設(shè)
- Hive數(shù)據(jù)倉(cāng)庫(kù)技術(shù)與應(yīng)用
- 數(shù)字的秘密生活:最有趣的50個(gè)數(shù)學(xué)故事
評(píng)論
0/150
提交評(píng)論