多線程程序設(shè)計(jì)-for-linux_第1頁(yè)
多線程程序設(shè)計(jì)-for-linux_第2頁(yè)
多線程程序設(shè)計(jì)-for-linux_第3頁(yè)
多線程程序設(shè)計(jì)-for-linux_第4頁(yè)
多線程程序設(shè)計(jì)-for-linux_第5頁(yè)
已閱讀5頁(yè),還剩60頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、聲明:本文是網(wǎng)上整理的資料,版權(quán)屬其作者本人所 有°第一章線程基礎(chǔ)知識(shí)-什么是線程在一個(gè)程序里的多個(gè)執(zhí)行路線就叫做線程。更準(zhǔn)確的定義是:線程是“一個(gè)進(jìn)程內(nèi)部的一個(gè)控制序列"。典型的imix進(jìn)程可以看成只有一個(gè)控制線程:一個(gè)進(jìn)程在同一時(shí)刻只做一 件事情。有了多個(gè)控制線程以后,在程序設(shè)計(jì)時(shí)可以把進(jìn)程設(shè)計(jì)成在同一時(shí)刻能 夠做不止一件事,每個(gè)線程處理各只獨(dú)立的任務(wù)。二線程的優(yōu)點(diǎn)(1 )通過(guò)為每種事件類型的處理分配單獨(dú)的線程,能夠簡(jiǎn)化處理異步時(shí)間的代碼。(2) 多個(gè)線程可以自動(dòng)共享相同的存儲(chǔ)地址空間和文件描述符。(3) 有些問(wèn)題可以通過(guò)將其分解從而改善整個(gè)程序的吞吐量。(4) 交互的

2、程序可以通過(guò)使用多線程實(shí)現(xiàn)相應(yīng)時(shí)間的改善,多線程可以把 程序中處理用戶輸入輸出的部分與其它部分分開(kāi)。三線程的缺點(diǎn)線程也有不足之處。編寫(xiě)多線程程序需要更全面更深入的思考。在一個(gè)多線程程序里因時(shí)間分配上的細(xì)微偏差或者因共享了不該共享的變量而造成不良 影響的可能性是很大的。調(diào)試一個(gè)多線程程序也比調(diào)試一個(gè)單線程程序困難得多四線程的結(jié)構(gòu)線程包含了表示進(jìn)程內(nèi)執(zhí)行環(huán)境必需的信息,其中包括進(jìn)程 中標(biāo)識(shí)線程的線程id一組寄存器值、棧、調(diào)度優(yōu)先級(jí)和策略、信號(hào)屏蔽子* errno變量以及線 程私有數(shù)據(jù)。進(jìn)程的所有信息對(duì)該進(jìn)程的所有線程都是共享的,包括可執(zhí)行的程 序文本程序的全局內(nèi)存和堆內(nèi)存、棧以及文件描述符。五線程

3、標(biāo)識(shí)就像每個(gè)進(jìn)程有一個(gè)進(jìn)程id樣,每個(gè)線程也有一個(gè)線程id,進(jìn)程id在 整個(gè)系統(tǒng)中是唯一的,但線程不同,線程id只在它所屬的進(jìn)程環(huán)境中有效。線 程id用pthread_t數(shù)據(jù)類型來(lái)表示實(shí)現(xiàn)的時(shí)候可以用一"結(jié)構(gòu)來(lái)代表pthread_t 數(shù)據(jù)類型所以可以移植的操作系統(tǒng)不能把它作為整數(shù)處理。因此必須使用函竅 來(lái)對(duì)來(lái)對(duì)兩個(gè)線程id進(jìn)行比較。名稱::pthread equal功能:比較兩個(gè)線程id頭文件:include <pthread.h>函數(shù)原形:int pthread equal(pthread t tidl,pthread t tid2);參數(shù):tidl 進(jìn)程 lid ti

4、d2 進(jìn)程 2id返回值:若相等返回非0值,否則返回02名稱:|pthread self功能:獲取自身線程的id頭文件:#include <pthread.h>函數(shù)原形:pthread t pthread self( void);參數(shù):無(wú)返回值:調(diào)用線程的線程id六線程的創(chuàng)建3名稱::?thread create功能:創(chuàng)建線理頭文件:#include <pthread.h>函數(shù)原形:int pthread_create(pthread_t restrict tidp,const pthread _attr_t restrict attr.void *(*start rt

5、n)(void),void restrict arg);參數(shù):返回值:若成功返回則返回0,否則返回錯(cuò)誤編號(hào)當(dāng)pthread.creat成功返回時(shí),tidp指向的內(nèi)存單元被設(shè)置為新創(chuàng)建線程的線程 id鎖t參藪用于定制各種不同的線程屬性??梢园阉O(shè)置為null,創(chuàng)建默認(rèn)的新創(chuàng)建的線程從start_rtn函數(shù)的地址開(kāi)始運(yùn)行,該函數(shù)只有一個(gè)無(wú)類型指 針參數(shù)arg,如果需要向start.rtn函數(shù)傳遞的參數(shù)不止一個(gè),那么需要把這些參數(shù) 放到一個(gè)結(jié)構(gòu)中,然后把疥個(gè)結(jié)構(gòu)的地址作為a咚參數(shù)傳入。#include vpthread.h>void printids(const char *s) printf

6、(u%s pid:%u tid:%u n“, s,getpid(),pthread_self();void *thr_fn(void *arg) printids(unew thread:");int main()int err; pthread_t tid; en-pthread_create(&tid,null,thr_fn,null); if(err=0)printfc'can't create thread:%snstrerror(err); printids(umain thread: “);sleep(l);exit(o);尖于進(jìn)程的編譯我們都要加

7、上參數(shù)-lpthread否則提示找不到函數(shù)的錯(cuò)誤。 具體編譯方法是 cc -lpthread -o gettid gettid.c 運(yùn)行結(jié)果為main thread: pid 14954 tid 134529024new thread: pid 14954 tid 134530048七線程的終止線程是依進(jìn)程而存在的當(dāng)進(jìn)程終止時(shí),線程也就終止了。 當(dāng)然也有在不終止整個(gè)進(jìn)程的情況下停止它的控制流。(1 )線程只是從啟動(dòng)例程中返回,返回值是線程的退出碼。(2 )縣城可以被同一進(jìn)程中的其他線程取消。(3 )線程調(diào)用 pthread_exit.4名 稱:|pthread exit功能:終止一個(gè)線程頭文件

8、:#include <pthread.h>函數(shù)原形:void pthread exit(void *rval ptr);參數(shù):返回值:無(wú)rvalprt是一個(gè)無(wú)類型指針,與傳給肓動(dòng)例程的單個(gè)參數(shù)類似。進(jìn)程中的其他 線程旨以調(diào)用pthreadjoin函數(shù)訪問(wèn)到這個(gè)指針。名稱::pthreadjoin功能:獲得進(jìn)程的終止?fàn)顟B(tài)頭文件:# include <pthread.h>函數(shù)原形:int pthreadjoin(pthread t thread,void *rval ptr);參數(shù):返回值:若成功返回0,否則返回錯(cuò)誤編號(hào)。5當(dāng)一個(gè)線程通過(guò)調(diào)用pthread.exit退出或者

9、簡(jiǎn)單地從肓動(dòng)歷程中返回時(shí)進(jìn)程 中的其他線程可以通過(guò)調(diào)用pthreadjoin函數(shù)獲得進(jìn)程的退出狀態(tài)。調(diào)用 pthreadjoin進(jìn)程將一直阻塞直到指定的線程調(diào)用pthread_exit,從肓動(dòng)例程中 或者被取消。如果線程只是從它的啟動(dòng)歷程返回 rval_ptr將包含返回碼。#include <pthread.h>#include <string.h>void *thr_fn l(void *arg)printfc'thread 1 returningn,); return(void *)1);void *thr_fn2(void *arg)printf(<

10、uthread 2 exitingn); return(void *)2);int main()pthread_t tidl,tid2;void *tret;pthread_create(&tid 1 ,null,thr_fn 1,null); pthread_create(&tid2,null, thr_fn2,null); pthreado in(tid 1,&tret);printf(<4thread 1 exit code %dn,(int)tret);pthread _join(tid2, &tret); printf(4<thread 2

11、 exit code %dn,(int)tret); exit(o);運(yùn)行結(jié)果是: thread 1 returning thread 2 exiting thread 1 exit code 1 thread 2 exit code 26 名稱::pthread detach功能:使線程進(jìn)天分離狀態(tài)。頭文件:幷include <pthread.h>函數(shù)原形:int pthread detach(pthread t tid);參數(shù):返回值:若成功則返回0 否則返回錯(cuò)誤編號(hào)。在默認(rèn)情況下,線程的終止?fàn)顟B(tài)會(huì)保存到對(duì)該線程調(diào)用pthreadjoin,如果線 程已經(jīng)處于分離狀態(tài)-線程的底層

12、存儲(chǔ)資源可以在線程終止時(shí)立即被收回。當(dāng)線 程被分離時(shí)并不能用pthreadjoin函數(shù)等待它的終止?fàn)顟B(tài)。對(duì)分離狀態(tài)的線 程進(jìn)行pthread_join的調(diào)用會(huì)產(chǎn)生失敗返回einval.pthread_detach調(diào) 用可以用于使線程進(jìn)入分離狀態(tài)。7名稱::pthread cancel功能:取消同一進(jìn)程中的其他線程頭文件:#include <pthread.h>函數(shù)原形:int pthread cancel(pthread t tid);參數(shù):tid線程id返回值:1若成功返回0 否則返回錯(cuò)誤編號(hào)。在默認(rèn)的情況下pthread_cancel函數(shù)會(huì)使由tid標(biāo)識(shí)的線程的行為表現(xiàn)為 如同

13、調(diào)用了參數(shù)為pthead_canceled的pthread_exit函數(shù),但是,線程可 以選擇忽略取消方式和控制曲消方式pthread.cancel并不等待線程終止,它僅 僅提出請(qǐng)求。名稱::pthread cancel push/ pthread cancel push pop功能:線程清理女理程岸頭文件:存include <pthread>h>函數(shù)原形:void pthread_cancel_push(void (*rtn)(void *) void *arg);void pthread cancel pop(int execute);參數(shù):rtn處理程序入口地址 arg

14、傳遞給處理函數(shù)的參數(shù)返回值:無(wú)8線程可以安排它退出時(shí)需要調(diào)用的函數(shù)這樣的函數(shù)稱為線程清理處理程序 線程可以建立多個(gè)清理處理程序。處理程序記錄在棧中也就是說(shuō)它們的執(zhí)行順 序與它們注冊(cè)時(shí)的順序相反。要注意的是如果線程是通過(guò)從他的肓動(dòng)例程中返回而終止的它的處理程 序就不會(huì)調(diào)用。還要注意清理處理程序是按照與它們安裝時(shí)相反的順序調(diào)用的。#include <pthread.h>#include <stdio.h>void cleanup(void *arg) printfc'cleanup: %sn,(char *)arg);void *thr_fn(void *arg)

15、/*線程入 口地址*/printf(66thread startn,>pthread_cleanup_push(cleanup,thread first handler'');/*設(shè)置第一 個(gè)線程處理程序*/pthread_cleanup_push(cleanup,thread second handler); /*設(shè)置 第二個(gè)線程亦里程序*/printfc'thread push completen);pthread_cleanup_pop(0); /*取消第一個(gè)線程處理程序*/ pthread_cleanup_pop(0); /*取消第二個(gè)線程處理程序*/in

16、t main()pthread_t tid; void *tret;pthread_creat(&tid,null,thr_fn,(void *)1); /*創(chuàng)建一個(gè)線程*/ pthreadjoin(tid,&tret); /*獲得線程終止?fàn)顟B(tài)*/ ptinrfc'thread exit code %dn,9,(int)tret);)、一次性初始化有時(shí)候我們需要對(duì)一些posix變量只進(jìn)行一次初始化,如線程鍵(我下面 會(huì)講到)。如果我們進(jìn)行多次初始化程序就會(huì)出現(xiàn)錯(cuò)誤。在傳統(tǒng)的順序編程中,一次性初始化經(jīng)常通過(guò)使用布爾變量來(lái)管理??刂?變量被靜態(tài)初始化為0,而任何依賴于初始化

17、的代碼都能測(cè)試該變量。如果變量 值仍然為0,則它能實(shí)行初始化,然后將變量置為1。以后檢查的代碼將跳過(guò)初 始化。但是在多線程程序設(shè)計(jì)中,事情就變的復(fù)雜的多。如果多個(gè)線程并發(fā)地執(zhí) 行初始化序列代碼,2個(gè)線程可能發(fā)現(xiàn)控制變量為0,并且都實(shí)行初始化,而 該過(guò)程本該僅僅執(zhí)行一次。初始化的狀態(tài)必須由互斥量保護(hù)。如果我們需要對(duì)一個(gè)posix變量靜態(tài)的初始化,可使用的方法是用一個(gè)互 斥量對(duì)該變量的初始話進(jìn)行控制。但有時(shí)候我們需要對(duì)該變量進(jìn)行動(dòng)態(tài)初始化, pthread_once就會(huì)方便的多。9.名稱:pthread once功能:次性初覓化頭文件:存include <pthread.h>函數(shù)原形:

18、pthread_once_t once_control=pthread_once_init; int pthread_once(pthread_once_t*o nce conti5void(*init routine)(void);參數(shù):once_control控制變量init routine初始化函數(shù)返回值:若成功返回0,若失敗返回錯(cuò)誤編號(hào)。類型為pthread_once_t的變量是一個(gè)控制變量??刂谱兞勘仨毷褂?pthread_once_init宏靜態(tài)地初始化。pthread_once函數(shù)首先檢查控制變量判斷是否已經(jīng)完成初始化如果 完成就簡(jiǎn)單地返回;否則,pthread_once調(diào)用初始

19、化函數(shù)并且記錄下初始 化被完成。如果在一個(gè)線程初始時(shí),另外的線程調(diào)用pthread_once *則調(diào)用線 程等待,直到那個(gè)現(xiàn)成完成初始話返回。下面就是該函數(shù)的程序例子:#include <pthread.h>pthread once t once=pthread once init;pthread_mutex_t mutex; /*互斥量我們后面會(huì)講到*/ void once_init_routine(void) /*次初始化函數(shù)*/int status;status=pthread_mutex_init(&mutex,null);/* 初始化互斥量 */ if(statu

20、s=o)printf(tnit success!,my id is %u,pthread_self();void *child_thread(void *arg)printf(t'm child ,my id is %u9,pthread_self(); pthread_once(&once,once_init_routine); /*子線程調(diào)用一次性初始化函 數(shù)*/int main(int argc,char *argv)pthread_t child_thread_id;pthread_create(&child_thread_id,null,child_threa

21、d,null);/* 創(chuàng)建 子線程*/printfctm fat her, my id is %u,pthread_self(); pthread_once(&once,once_initoutine);/* 父線程調(diào)用一次性初始化函 數(shù)*/pthreadjoin(child_thread_id,null);程序運(yùn)行結(jié)果如下:./oncefm father,my id is 3086874304init success!,my id is 3086874304i'm child, my id is 3086871472從上面的結(jié)果可以看到當(dāng)主函數(shù)初始化成功后子函數(shù)初始化失敗。九

22、、線程的私有數(shù)據(jù)在進(jìn)程內(nèi)的所有線程共享相同的地址空間任何聲明為靜 態(tài)或外部的變量,或在進(jìn)程堆聲明的變量都可以被進(jìn)程所有的線程讀寫(xiě)。那怎樣才能使線程序擁 有自己的私有數(shù)據(jù)呢。posix提供了一種方法,創(chuàng)建線程鍵。名稱::pthread key create功能:建立線程菽有藪據(jù)鍵頭文件:/include <pthread.h>函數(shù)原形:int pthread_key_create(pthread_key_t *key,void(*destructor)(void *);參數(shù):key私有數(shù)據(jù)鍵destructor 清理函數(shù)返回值: 匿成功返回0,若失敗返回錯(cuò)誤編號(hào)。第一個(gè)參數(shù)為指向一個(gè)

23、鍵值的指針,第二個(gè)參數(shù)指明了一個(gè)destructor函數(shù) (清理函數(shù)),如果這個(gè)參數(shù)不為空,那么當(dāng)每個(gè)線程結(jié)束時(shí),系統(tǒng)將調(diào)用這 個(gè)函數(shù)來(lái)釋放綁定在這個(gè)鍵上的內(nèi)存塊。這個(gè)函數(shù)常和函數(shù)pthread_once 起使用,為了讓這個(gè)鍵只被創(chuàng)建一次。函數(shù)pthread.once聲明一個(gè)初始化函 數(shù)*第一次調(diào)用pthread_once時(shí)它執(zhí)行這個(gè)函數(shù)以后的調(diào)用將被它忽略。下面是程序例子:#include <pthread.h>pthread_key_t tsd_key; pthread_once_t key_once=pthread_once_init;void once_routine(vo

24、id)int status;status=pthread_key_create(&tsd_key,null);/* 初始化線程私有數(shù)據(jù) 鍵*/if(status=o)printfc'key create success! my id is %un,pthread_self();void *child_thread(void *arg)printf(t'm child,my id is %un'pthreadselfo); pthread_once(&key_once,once_routine);/* 調(diào)用次性初始化函數(shù)*/ int main(int ar

25、gc,char *argv| )pthread_t child_thread_id;pthread create (&child thread id,null,child thread,null);printfctm father,my id is%un?pthread_self(); pthread_once (&key_once,once_routine);程序運(yùn)行結(jié)果如下:fm father,my id is 3086231232key create success! my id is 3086231232i'm child,my id is 2086228400

26、第二章線程高級(jí)知識(shí)線程屬性線程具有屬性.用pthread_attr_t表示,在對(duì)該結(jié)構(gòu)進(jìn)行處理之前必須進(jìn)行 初始化,在使用后需要對(duì)其去嗓初始化。我們用pthread_attr_init函數(shù)對(duì)其初始化, 用pthread_attr_destroy對(duì)其去除初始化。1 -名稱::pthread attr init/pthread attr destroy功能:對(duì)線程焉性初始化法涇初始化頭文件:#include <pthread.h>函數(shù)原形:int pthread_attr_init(pthread_attr_t *attr); int pthread attr destroy(pthr

27、ead attr t *attr);參數(shù):attr線程雇性變量返回值:若成功返回0 *若失敗返回1 °調(diào)用pthread_attr_init 后 pthread_t結(jié)構(gòu)所包含的內(nèi)容就是操作系統(tǒng)實(shí)現(xiàn)支持 的線程所有屬性的默認(rèn)值。如果要去除對(duì)pthread_attr_t結(jié)構(gòu)的初始化可以調(diào)用pthread_attr_destroy 函數(shù)°如果pthread_attr_init實(shí)現(xiàn)時(shí)為屬性對(duì)象分配了動(dòng)態(tài)內(nèi)存空間 pthread_attr_destroy還會(huì)用無(wú)效的值初始化屬性對(duì)象因此如果經(jīng) pthread_attr_destroy 去除初始化之后的 pthread_attr_t 結(jié)

28、構(gòu)被 pthread_create 函數(shù) 調(diào)用病會(huì)導(dǎo)致其返回錯(cuò)誤。線程屬性結(jié)構(gòu)如下: typedef structintintstruct sched_paramintintsize_tintdetachstate;線程的分離狀態(tài) schedpolicy;線程調(diào)度策略schedparam;線程的調(diào)度參數(shù) inheritsched;線程的繼承性 scope;線程的作用域guardsize;線程棧末尾的警戒緩沖區(qū)大小 stackaddr_set;void * size_t pthread_attr_t;每個(gè)個(gè)屬性都對(duì)應(yīng)些函數(shù)對(duì)其查看或修改。下面我們分別介紹。stackaddr;線程棧的位置stac

29、ksize;線程棧的大小二、線程的分離狀態(tài)線程的分離狀態(tài)決定一個(gè)線程以什么樣的方式來(lái)終止自己。在默認(rèn)情況下 線程是非分離狀態(tài)的,這種情況下,原有的線程等待創(chuàng)建的線程結(jié)束。只有當(dāng) pthreadjoin ()函數(shù)返回時(shí),創(chuàng)建的線程才算終止,才能釋放自己占用的系 統(tǒng)資源。而分離線程不是這樣子的,它沒(méi)有被其他的線程所等待,自己運(yùn)行結(jié)束了, 線程也就終止了 馬上釋放系統(tǒng)資源。程序員應(yīng)該根據(jù)自己的需要,選擇適當(dāng)?shù)?分離狀態(tài)。所以如果我們?cè)趧?chuàng)建線程時(shí)就知道不需要了解線程的終止?fàn)顟B(tài),則可 以pthread_attr_t結(jié)構(gòu)中的detachstate線程屬性,讓線程以分離狀態(tài)啟動(dòng)。名稱:|pthread at

30、tr getdetachstate/pthread attr setdetachstate功能:獲取/修改線程的分離狀態(tài)屬性頭文件:#include <pthread.h>函數(shù)原形:int pthread_attr_getdetachstate(const pthread_attr_t * attaint* detachstate);int pthread attr setdetachstate(pthread attr t *attr,int detachstate);參數(shù):attr線程雇性變量detachstate線程的分離狀態(tài)屬性返回值:若成功返回0,若失敗返回1。2可以使用

31、pthread_attr_setdetachstate函數(shù)把線程屬性detachstate設(shè)置為下面 的兩個(gè)合法值之一:設(shè)置為pthread_create_detached,以分離狀態(tài)肓動(dòng) 線程;或者設(shè)置為pthread_create_joinable,正常肓動(dòng)線程。可以使用 pthread_attr_getdetachstate 函數(shù)獲取當(dāng)前的 datachstate 線程屬性。以分離狀態(tài)創(chuàng)建線程#iinclude <pthread.h>void child_thread(void *arg)printf(uchild thread run!n);int main(int arg

32、c,char *argv)pthread_t tid;pthread attr t attr;pthread_attr_i n i t (& attr);pthread_attr_setdetachstate(&attr,pthread_create_detached); pthread_create(&tid,&attr,fn,arg);pthread_attr_destroy(&attr);sleep(l);三、線程的繼承性函數(shù) pthread_attr_setinheritsched 和 pthread_attr_getinheritsched 分

33、別用來(lái)設(shè) 置和得到線程的麵承應(yīng)這兩個(gè)函數(shù)的定義如卞:3.名稱:lpthread attr getinheritschedpthread attr setinheritsched功能:獲得/設(shè)置線程的繼承性頭文件:include <pthread.h>函數(shù)原形:int pthread_attr_getinheritsched(const pthread_attr_t * attaint inheritsched);int pthread_attr_setinheritsched(pthread_attr_t *attr,int inheritsched);參數(shù):attr線程屬性變量i

34、nheritsched線程的繼承性返回值:若成功返回0 *若失敗返回1。這兩個(gè)函數(shù)具有兩個(gè)參數(shù),第1個(gè)是指向?qū)傩詫?duì)象的指針,第2個(gè)是繼承性或 指向繼承性的指針。繼承性決定調(diào)度的參數(shù)是從創(chuàng)建的進(jìn)程中繼承還是使用在 schedpolicy和schedparam屬性中顯式設(shè)置的調(diào)度信息°pthreads不為inheritsched 指定默認(rèn)值,因此如果你尖心線程的調(diào)度策略和參數(shù),必須先設(shè)置該屬性。繼承性的可能值是pthread_inherit_sched (表示新線程將繼承創(chuàng)建 線程的調(diào)度策略和參數(shù))和pthread_explicit_sched (表示使用在 schedpolicy和sc

35、hedparam屬性中顯式設(shè)置的調(diào)度策略和參數(shù))。如果你需要顯式的設(shè)置一個(gè)線程的調(diào)度策略或參數(shù)那么你必須在設(shè)置之 前將 inheritsched 屬性設(shè)置為 pthread_explicit_sched.下面我來(lái)講進(jìn)程的調(diào)度策略和調(diào)度參數(shù)。我會(huì)結(jié)合下面的函數(shù)給出本函數(shù) 的程序例子。四、線程的調(diào)度策略函數(shù) pthread_attr_setschedpolicy 和 pthread_attr_getschedpolicy 分別用來(lái)設(shè)置 和得到線程的調(diào)應(yīng)策略。名稱::pthread_attr_getschedpolicy pthread attr setschedpolicy功能:獲得/設(shè)置纟

36、63;程的調(diào)度策略頭文件:#include <pthread.h>函數(shù)原形:int pthread_attr_getschedpolicy(const pthread_attr_t * attaint *policy);int pthread attr setschedpolicy (pthread attr t * attaint policy);參數(shù):attr壓程屬性變量policy調(diào)度策略返回值:若成功返回0,若失敗返回1。這兩個(gè)函數(shù)具有兩個(gè)參數(shù).第1個(gè)參數(shù)是指向?qū)傩詫?duì)象的指針.第2個(gè)參數(shù)是 調(diào)度策略或指向調(diào)度策略的指針。調(diào)度策略可能的值是先進(jìn)先出(sched_fifo )、

37、輪轉(zhuǎn)法(sched_rr ),或其它(sched_other )。sched_fifo策略允許一個(gè)線程運(yùn)行直到有更高優(yōu)先級(jí)直線程準(zhǔn)備好,或 者直到它自愿阻塞自己。在sched.fifo調(diào)度策略下當(dāng)有一個(gè)線程準(zhǔn)備好時(shí) 除非有平等或更高優(yōu)先級(jí)的線程已經(jīng)在運(yùn)行,否則它會(huì)很快開(kāi)始執(zhí)行。sched_rr(輪循)策略是基本相同的不同之處在于:如果有一個(gè)sched_rr策略的線程執(zhí)行了超過(guò)一個(gè)固定的時(shí)期(時(shí)間片間隔)沒(méi)有阻塞, 而另外閔sched_rr或schbd_fip0策略的相同優(yōu)先級(jí)的線程準(zhǔn)備好時(shí),運(yùn) 行的線程將被搶占以便準(zhǔn)備好的線程可以執(zhí)行。當(dāng)有sched_fifo或sched_rr策賂的線程在一個(gè)

38、條件變量上等持或等持 加鎖同一個(gè)互斥量時(shí),它們將以屆先級(jí)順序被喚醒。即,如果一個(gè)低優(yōu)先級(jí)的 sched_fifo線程和一個(gè)高優(yōu)先織的sched.fifo線程都在等待鎖相同的互斥 且,則雪互斥量被解鎖時(shí),高優(yōu)先級(jí)線程將總是被首先解除阻塞。五、線程的調(diào)度參數(shù)函數(shù) pthread_attr_getschedparam 和 pthread_attr_setschedparam 分別用來(lái)設(shè) 置和得到線程的論度參數(shù)。名稱::pthread_attr_getschedparam pthread attr setschedparam功能:獲得/設(shè)置纟£程的調(diào)度參數(shù)頭文件:include <pt

39、hread.h>函數(shù)原形:int pthread_attr_getschedparam(const pthread_attr_t *attr,struct sched_param *param);int pthread_attr_setschedparam(pthread_attr_t *attr,const struct sched param * param);參數(shù):attr線程屬性變量paramsched param 結(jié)構(gòu)返回值:若成功返回0,若失敗返回1。這兩個(gè)函數(shù)具有兩個(gè)參數(shù),第1個(gè)參數(shù)是指向?qū)傩詫?duì)象的指針,第2個(gè)參數(shù)是 sched_param結(jié)構(gòu)或指向該結(jié)構(gòu)的指針°

40、結(jié)構(gòu)sched_param在文件/usr/include /bits/sched.h中定義如下:struct sched_paramint sched_priority;;結(jié)構(gòu)sched_param的子成員sched_priority控制一個(gè)優(yōu)先權(quán)值大的優(yōu)先權(quán)值 對(duì)應(yīng)高的優(yōu)先權(quán)。系統(tǒng)支持的最大和最小優(yōu)先權(quán)值可以用sched_get_priority_max 函數(shù)和sched_get_priority_min函數(shù)分別得到°注意:如果不是編寫(xiě)實(shí)時(shí)程序不建議修改線程的優(yōu)先級(jí)。因?yàn)椋{(diào)度策略 是一件非常復(fù)雜的事情,如果不正確使用會(huì)導(dǎo)致程序錯(cuò)誤從而導(dǎo)致死鎖等問(wèn) 題。如:在多線程應(yīng)用程序中為線程

41、設(shè)置不同的優(yōu)先級(jí)別,有可能因?yàn)楣蚕碣Y源 而導(dǎo)致優(yōu)先級(jí)倒置。名稱::sched_get_priority_max sched get priority min功能:獲得系統(tǒng)女持的纟 壬程優(yōu)先權(quán)的最大和最小值頭文件:#include <pthread.h>函數(shù)原形:int sched_get_priority_max(int policy); int sched get priority min(int policy);參數(shù):policy系統(tǒng)支扌翕勺線程優(yōu)先權(quán)的最大和最小值返回值:若成功返回0,若失敗返回1。下面是上面幾個(gè)函數(shù)的程序例子:#include <pthread.h&g

42、t;#include <sched.h>void *child_thread(void *arg)int policy;int max_priority,min_priority;struct sched_param param;pthread_attr_t attr;pthread_attr_init(&attr);/*初始化線程屬性變量*/ pthread_attr_setinheritsched(&atgpthread_explicit_sched);/*設(shè)置線 程繼承性*/pthread_attr_getinheritsched(&attr,&

43、;policy); /*獲得線程的繼承性*/ if(policy=pthread_explicit_sched)printf(“inheritsched:pthread_explicit_schedn"); if(policy=pthreadnherit_sched)printfcinheritsched:pthread_inherit_schedn'');pthread_attr_setschedpolicy(&attr,sched_rr);/* 設(shè)置線程調(diào)度策略 */ pthread_attr_getschedpolicy(&attr,&p

44、olicy);/* 取得線程的調(diào)度策略 */ impolicy二二sched_fifo)pi'intfcschedpolicyischedfifo'n");if(policy=sched_rr) printf(<<schedpolicy:sched_rrn,?);if(policy=sched_other) printf(“schedpolicy:sched_otherit);sched_get_piority_max(max_priority);/*獲得系統(tǒng)支持的線程優(yōu)先權(quán)的最大值 */sched_get_priority_min(min_priorit

45、y);/*獲得系統(tǒng)支持的線程優(yōu)先權(quán)的最小值 */printf(4umax priority:%un,max_priority); printf(<amin priority:%un'',min_piiofity);param.sched_priority=max_priority;pthread_attr_setschedparam(&attr,&param) ;/* 設(shè)置線程的調(diào)度參數(shù)*/ printfctsched_priority:%un,param.sched_priority);/* 獲得線程的調(diào)度參數(shù) */ pthread_attr_destr

46、oy(&attr);int main(int argc,char *argv) pthread_t child_thread_id;pthread_create(&child_thread_id,null,child_thread,null); pthreado in(child_thread_id,null);六、線程的作用域函數(shù)pthread_attr_setscope和pthread_attr_getscope分別用來(lái)設(shè)置和得到線程 的作用域,這兩個(gè)函竅的定義如下:7 名稱::pthread_attr_setscope pthread attr getscope功能:獲得

47、/設(shè)置線程的作用域頭文件:#include <pthread.h>函數(shù)原形:int pthread_attr_setscope(pthread_attr_t * attaint scope); int pthread attr getscope(const pthread attr t * attaint * scope);參數(shù):attr線程屬性變量scope線程的作用域返回值:若成功返回0 若失敗返回1。這兩個(gè)函數(shù)具有兩個(gè)參數(shù),第1個(gè)是指向?qū)傩詫?duì)象的指針第2個(gè)是作用域或 指向作用域的指針,作用域控制線程是否在進(jìn)程內(nèi)或在系統(tǒng)級(jí)上競(jìng)爭(zhēng)資源可 能的值是pthread_scope_pro

48、cess (進(jìn)程內(nèi)競(jìng)爭(zhēng)資源) pthread_scope_system.(系統(tǒng)級(jí)上競(jìng)爭(zhēng)資源)。七、線程堆棧的大小函數(shù) pthread_attr_setstacksize 和 pthread_attr_getstacksize 分別用來(lái)設(shè)置和得 到線程堆棧的大小,直兩個(gè)函數(shù)的定義如下亦示:8 名稱::pthread_attr_getdetstacksize pthread attr setstacksize功能:獲得/修改纟£程棧的大小頭文件:include <pthread.h>函數(shù)原形:int pthread_attr_getstacksize(const pthrea

49、d_attr_t * restrict attr5size_t restrict stacksize);int pthread attr setstacksize(pthread attr t *attr ,size t * stacksize);參數(shù):attr鳥(niǎo)程富性變量stacksize堆棧大小返回值:若成功返回0,若失敗返回1。這兩個(gè)參數(shù)具有兩個(gè)參數(shù)-第1個(gè)是指向?qū)傩詫?duì)象的指針第2個(gè)是堆棧大小 或指向堆棧大小的指針如果希望改變棧的默認(rèn)大小,但又不想自己處理線程棧的分配問(wèn)題,這時(shí) 使用pthread_attr_setstacksize函數(shù)就非常用用°)、線程堆棧的地址函數(shù) pth

50、read_attr_setstackaddr 和 pthread_attr_getstackaddr 分別用來(lái)設(shè)置和 得到線程堆棧的在置,這兩個(gè)函數(shù)的定義如卞:名稱::pthread_attr_setstackaddr pthread attr_getstackaddr功能:獲得/修改線程棧的位置頭文件:include <pthread.h>函數(shù)原形:int pthread_attr_getstackaddr(const pthread_attr_t *attr.void *stackaddf);int pthread attr setstackaddr(pthread attr

51、t attr.void *stackaddr);參數(shù):attr壓程屬性變量stackaddr堆棧地址返回值:若成功返回0,若失敗返回1。9.這兩個(gè)函數(shù)具有兩個(gè)參數(shù),第1個(gè)是指向?qū)傩詫?duì)象的指針,第2個(gè)是堆棧地址 或指向堆棧地址的指針。九、線程棧末尾的警戒緩沖區(qū)大小函數(shù) pthread_attr_getguardsize 和 pthread_attr_setguardsize 分別用來(lái)設(shè)置和 得到線程棧末尾前警況緩沖區(qū)大小這兩個(gè)扇數(shù)6勺定義如下:名稱::pthread_attr_getguardsize pthread attr setguardsize功能:獲得/修改妊程棧末尾的警戒緩沖區(qū)大小頭

52、文件:#include <pthread.h>函數(shù)原形:int pthread_attr_getguardsize(const pthread_attr_t restrict attr,size* restrict guardsize);int pthread attr setguardsize(pthread attr t *attr ,size t *guardsize);參數(shù):返回值:若成功返回0 *若失敗返回1。10.線程屬性guardsize控制著線程棧末尾之后以避免棧溢出的擴(kuò)展內(nèi)存大小。這個(gè) 屬性默認(rèn)設(shè)置為pagesize個(gè)字節(jié)??梢园裧uardsize線程屬性設(shè)為0,

53、從而不允 許屬性的這種特征行為發(fā)生:在這種情況下不會(huì)提供警戒緩存區(qū)。同樣地,如果 對(duì)線程屬性stackaddr作了修改,系統(tǒng)就會(huì)假設(shè)我們會(huì)自己管理?xiàng)?,并使警戒?緩沖區(qū)機(jī)制無(wú)效,等同于把guardsize線程屬性設(shè)為0。第三章posix有名信號(hào)燈函數(shù)sem_open創(chuàng)建一個(gè)新的有名信號(hào)燈或打開(kāi)一個(gè)已存在的有名信號(hào)燈。 有名信號(hào)燈總是既可用于線程間的同步,又可以用于進(jìn)程間的同步。、posix有名信號(hào)燈函數(shù)1.名稱::sem open功能:創(chuàng)僵并初始化有名信號(hào)燈頭文件:#include <semaphore.h>函數(shù)原形:sem_t *sem_open(const char *name

54、jnt oflag,/*mode_t mode,unsigned int value*/);參數(shù):name信號(hào)燈的外部名字oflag選擇創(chuàng)建或打開(kāi)一個(gè)現(xiàn)有的信號(hào)燈 mode權(quán)限位value信號(hào)燈初始值返回值:成功時(shí)返回指向信號(hào)燈的指針,出錯(cuò)時(shí)為sem failedoflag參數(shù)可以是0、o_creat (創(chuàng)建一個(gè)信號(hào)燈)或o_creat|o_excl (如 果沒(méi)有指定的信號(hào)燈就創(chuàng)建),如果指定了 o-creat *菽么第三個(gè)和第四個(gè)參 數(shù)是需要的;其中mode參數(shù)指定權(quán)限位 value參數(shù)指定信號(hào)燈的初始值,通 常用來(lái)指定共享資源的書(shū)面。該初始不能超過(guò)sem_value_max 這個(gè)常值必 須

55、低于為32767。二值信號(hào)燈的初始值通常為1,存數(shù)信號(hào)廳的初始值則往往大 于1。如果指定了 o-creat (而沒(méi)有指定o_excl ),那么只有所需的信號(hào)燈 尚未存在時(shí)才初始化它。所需信號(hào)燈已存在條件下指定o_creat不是一個(gè)錯(cuò)誤 該標(biāo)志的意思僅僅是“如果所需信號(hào)燈尚未存在那就創(chuàng)霍并初始化它"。但是所 需信號(hào)燈等已存在條件下指定o_creat|o_excl卻是一個(gè)錯(cuò)誤。sem_open返回指向信號(hào)燈的指旺,該結(jié)構(gòu)里記錄著當(dāng)前共享資源的 數(shù)目。/* semopen.c */#include <semaphore.h>#include <unistd.h>#i

56、nclude <stdio.h>#include <stdlib.h>#include <fcntl.h>int main(int argc,char *argv)sem_t *sem;if(argc!=2)printf(t4please input a file name!n); exit(l);sem=sem_open(argv 1 ,o_creat,0644,1); exit(o);#gcc -lpthread -o semopen semopen.c #./semopen名稱::sem close功能:尖i切有名信號(hào)燈頭文件:#include <

57、;semaphore.h>函數(shù)原形:int sem close(sem t *sem);參數(shù):sem指商信號(hào)燈曲旨針?lè)祷刂担喝舫晒t返回0,否則返回1。2.個(gè)進(jìn)程終止時(shí),內(nèi)核還對(duì)其上仍然打開(kāi)著的所有有名信號(hào)燈自動(dòng)執(zhí)行這樣 的信號(hào)燈尖閉操作。不論該進(jìn)程是自愿終止的還是非自愿終止的,這種自動(dòng)尖閉 都會(huì)發(fā)生°但應(yīng)注意的是尖閉一個(gè)信號(hào)燈并沒(méi)有將它從系統(tǒng)中刪除。這就是說(shuō),posix 有名信號(hào)燈至少是隨內(nèi)核持續(xù)的:即使當(dāng)前沒(méi)有進(jìn)程打開(kāi)著某個(gè)信號(hào)燈,它的 值仍然保持。名稱::sem unlink功能:從系統(tǒng)中刪除信號(hào)燈頭文件:include <semaphore.h>函數(shù)原形:int sem un

溫馨提示

  • 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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論