• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 297,  comments - 15,  trackbacks - 0
            這是一個關(guān)于Posix線程編程的專欄。作者在闡明概念的基礎(chǔ)上,將向您詳細講述Posix線程庫API。本文是第一篇將向您講述線程的創(chuàng)建與取消。
            一、線程創(chuàng)建
            1.1 線程與進程
            相對進程而言,線程是一個更加接近于執(zhí)行體的概念,它可以與同進程中的其他線程共享數(shù)據(jù),但擁有自己的棧空間,擁有獨立的執(zhí)行序列。在串行程序基礎(chǔ)上引入線程和進程是為了提高程序的并發(fā)度,從而提高程序運行效率和響應(yīng)時間。
            線程和進程在使用上各有優(yōu)缺點:線程執(zhí)行開銷小,但不利于資源的管理和保護;而進程正相反。同時,線程適合于在SMP機器上運行,而進程則可以跨機器遷移。
            1.2 創(chuàng)建線程
            POSIX通過pthread_create()函數(shù)創(chuàng)建線程,API定義如下:
            int  pthread_create(pthread_t  *  thread, pthread_attr_t * attr, 
            void * (*start_routine)(void *), void * arg)
            與fork()調(diào)用創(chuàng)建一個進程的方法不同,pthread_create()創(chuàng)建的線程并不具備與主線程(即調(diào)用pthread_create()的線 程)同樣的執(zhí)行序列,而是使其運行start_routine(arg)函數(shù)。thread返回創(chuàng)建的線程ID,而attr是創(chuàng)建線程時設(shè)置的線程屬性 (見下)。pthread_create()的返回值表示線程創(chuàng)建是否成功。盡管arg是void *類型的變量,但它同樣可以作為任意類型的參數(shù)傳給start_routine()函數(shù);同時,start_routine()可以返回一個void *類型的返回值,而這個返回值也可以是其他類型,并由pthread_join()獲取。
            1.3 線程創(chuàng)建屬性
            pthread_create()中的attr參數(shù)是一個結(jié)構(gòu)指針,結(jié)構(gòu)中的元素分別對應(yīng)著新線程的運行屬性,主要包括以下幾項:
            __detachstate,表示新線程是否與進程中其他線程脫離同步,如果置位則新線程不能用pthread_join()來同步,且在退出時自行釋放 所占用的資源。缺省為PTHREAD_CREATE_JOINABLE狀態(tài)。這個屬性也可以在線程創(chuàng)建并運行以后用pthread_detach()來設(shè) 置,而一旦設(shè)置為PTHREAD_CREATE_DETACH狀態(tài)(不論是創(chuàng)建時設(shè)置還是運行時設(shè)置)則不能再恢復(fù)到 PTHREAD_CREATE_JOINABLE狀態(tài)。
            __schedpolicy,表示新線程的調(diào)度策略,主要包括SCHED_OTHER(正常、非實時)、SCHED_RR(實時、輪轉(zhuǎn)法)和 SCHED_FIFO(實時、先入先出)三種,缺省為SCHED_OTHER,后兩種調(diào)度策略僅對超級用戶有效。運行時可以用過 pthread_setschedparam()來改變。
            __schedparam,一個struct sched_param結(jié)構(gòu),目前僅有一個sched_priority整型變量表示線程的運行優(yōu)先級。這個參數(shù)僅當(dāng)調(diào)度策略為實時(即SCHED_RR 或SCHED_FIFO)時才有效,并可以在運行時通過pthread_setschedparam()函數(shù)來改變,缺省為0。
            __inheritsched,有兩種值可供選擇:PTHREAD_EXPLICIT_SCHED和PTHREAD_INHERIT_SCHED,前者表 示新線程使用顯式指定調(diào)度策略和調(diào)度參數(shù)(即attr中的值),而后者表示繼承調(diào)用者線程的值。缺省為PTHREAD_EXPLICIT_SCHED。
            __scope,表示線程間競爭CPU的范圍,也就是說線程優(yōu)先級的有效范圍。POSIX的標準中定義了兩個值: PTHREAD_SCOPE_SYSTEM和PTHREAD_SCOPE_PROCESS,前者表示與系統(tǒng)中所有線程一起競爭CPU時間,后者表示僅與同 進程中的線程競爭CPU。目前LinuxThreads僅實現(xiàn)了PTHREAD_SCOPE_SYSTEM一值。
            pthread_attr_t結(jié)構(gòu)中還有一些值,但不使用pthread_create()來設(shè)置。
            為了設(shè)置這些屬性,POSIX定義了一系列屬性設(shè)置函數(shù),包括pthread_attr_init()、pthread_attr_destroy()和與各個屬性相關(guān)的pthread_attr_get---/pthread_attr_set---函數(shù)。
            1.4 線程創(chuàng)建的Linux實現(xiàn)
            我們知道,Linux的線程實現(xiàn)是在核外進行的,核內(nèi)提供的是創(chuàng)建進程的接口do_fork()。內(nèi)核提供了兩個系統(tǒng)調(diào)用__clone()和fork (),最終都用不同的參數(shù)調(diào)用do_fork()核內(nèi)API。當(dāng)然,要想實現(xiàn)線程,沒有核心對多進程(其實是輕量級進程)共享數(shù)據(jù)段的支持是不行的,因 此,do_fork()提供了很多參數(shù),包括CLONE_VM(共享內(nèi)存空間)、CLONE_FS(共享文件系統(tǒng)信息)、CLONE_FILES(共享文 件描述符表)、CLONE_SIGHAND(共享信號句柄表)和CLONE_PID(共享進程ID,僅對核內(nèi)進程,即0號進程有效)。當(dāng)使用fork系統(tǒng) 調(diào)用時,內(nèi)核調(diào)用do_fork()不使用任何共享屬性,進程擁有獨立的運行環(huán)境,而使用pthread_create()來創(chuàng)建線程時,則最終設(shè)置了所 有這些屬性來調(diào)用__clone(),而這些參數(shù)又全部傳給核內(nèi)的do_fork(),從而創(chuàng)建的"進程"擁有共享的運行環(huán)境,只有棧是獨立的,由 __clone()傳入。
            Linux線程在核內(nèi)是以輕量級進程的形式存在的,擁有獨立的進程表項,而所有的創(chuàng)建、同步、刪除等操作都在核外pthread庫中進行。pthread 庫使用一個管理線程(__pthread_manager(),每個進程獨立且唯一)來管理線程的創(chuàng)建和終止,為線程分配線程ID,發(fā)送線程相關(guān)的信號 (比如Cancel),而主線程(pthread_create())的調(diào)用者則通過管道將請求信息傳給管理線程。
            二、線程取消
            2.1 線程取消的定義
            一般情況下,線程在其主體函數(shù)退出的時候會自動終止,但同時也可以因為接收到另一個線程發(fā)來的終止(取消)請求而強制終止。
            2.2 線程取消的語義
            線程取消的方法是向目標線程發(fā)Cancel信號,但如何處理Cancel信號則由目標線程自己決定,或者忽略、或者立即終止、或者繼續(xù)運行至Cancelation-point(取消點),由不同的Cancelation狀態(tài)決定。
            線程接收到CANCEL信號的缺省處理(即pthread_create()創(chuàng)建線程的缺省狀態(tài))是繼續(xù)運行至取消點,也就是說設(shè)置一個CANCELED狀態(tài),線程繼續(xù)運行,只有運行至Cancelation-point的時候才會退出。
            2.3 取消點
            根據(jù)POSIX標準,pthread_join()、pthread_testcancel()、pthread_cond_wait()、 pthread_cond_timedwait()、sem_wait()、sigwait()等函數(shù)以及read()、write()等會引起阻塞的系 統(tǒng)調(diào)用都是Cancelation-point,而其他pthread函數(shù)都不會引起Cancelation動作。但是pthread_cancel的手 冊頁聲稱,由于LinuxThread庫與C庫結(jié)合得不好,因而目前C庫函數(shù)都不是Cancelation-point;但CANCEL信號會使線程從阻 塞的系統(tǒng)調(diào)用中退出,并置EINTR錯誤碼,因此可以在需要作為Cancelation-point的系統(tǒng)調(diào)用前后調(diào)用 pthread_testcancel(),從而達到POSIX標準所要求的目標,即如下代碼段:
            pthread_testcancel();
                retcode = read(fd, buffer, length);
                pthread_testcancel();
            2.4 程序設(shè)計方面的考慮
            如果線程處于無限循環(huán)中,且循環(huán)體內(nèi)沒有執(zhí)行至取消點的必然路徑,則線程無法由外部其他線程的取消請求而終止。因此在這樣的循環(huán)體的必經(jīng)路徑上應(yīng)該加入pthread_testcancel()調(diào)用。
            2.5 與線程取消相關(guān)的pthread函數(shù)
            int pthread_cancel(pthread_t thread)
            發(fā)送終止信號給thread線程,如果成功則返回0,否則為非0值。發(fā)送成功并不意味著thread會終止。
            int pthread_setcancelstate(int state, int *oldstate)
            設(shè)置本線程對Cancel信號的反應(yīng),state有兩種值:PTHREAD_CANCEL_ENABLE(缺省)和 PTHREAD_CANCEL_DISABLE,分別表示收到信號后設(shè)為CANCLED狀態(tài)和忽略CANCEL信號繼續(xù)運行;old_state如果不為 NULL則存入原來的Cancel狀態(tài)以便恢復(fù)。
            int pthread_setcanceltype(int type, int *oldtype)
            設(shè)置本線程取消動作的執(zhí)行時機,type由兩種取值:PTHREAD_CANCEL_DEFFERED和 PTHREAD_CANCEL_ASYCHRONOUS,僅當(dāng)Cancel狀態(tài)為Enable時有效,分別表示收到信號后繼續(xù)運行至下一個取消點再退出和 立即執(zhí)行取消動作(退出);oldtype如果不為NULL則存入運來的取消動作類型值。
            void pthread_testcancel(void)
            檢查本線程是否處于Canceld狀態(tài),如果是,則進行取消動作,否則直接返回。
            轉(zhuǎn)自:

            posted on 2009-11-25 15:22 chatler 閱讀(744) 評論(0)  編輯 收藏 引用 所屬分類: Linux_Coding
            <2009年4月>
            2930311234
            567891011
            12131415161718
            19202122232425
            262728293012
            3456789

            常用鏈接

            留言簿(10)

            隨筆分類(307)

            隨筆檔案(297)

            algorithm

            Books_Free_Online

            C++

            database

            Linux

            Linux shell

            linux socket

            misce

            • cloudward
            • 感覺這個博客還是不錯,雖然做的東西和我不大相關(guān),覺得看看還是有好處的

            network

            OSS

            • Google Android
            • Android is a software stack for mobile devices that includes an operating system, middleware and key applications. This early look at the Android SDK provides the tools and APIs necessary to begin developing applications on the Android platform using the Java programming language.
            • os161 file list

            overall

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            99久久精品免费看国产一区二区三区 | 亚洲精品国产自在久久| 国内精品久久久久久久影视麻豆| 国产真实乱对白精彩久久| 亚洲va久久久噜噜噜久久狠狠| 久久强奷乱码老熟女| 久久婷婷色综合一区二区| 久久99热精品| 久久人人超碰精品CAOPOREN | 国产成人香蕉久久久久| 久久久久一区二区三区| 久久精品国产一区二区| 久久丫精品国产亚洲av| 91久久精品国产免费直播| 精品久久久久久久中文字幕| 伊人久久大香线蕉综合热线| 久久这里只有精品首页| 麻豆成人久久精品二区三区免费 | 亚洲欧美另类日本久久国产真实乱对白| 伊人丁香狠狠色综合久久| 久久天天躁狠狠躁夜夜av浪潮 | 久久久久久曰本AV免费免费| 亚洲αv久久久噜噜噜噜噜| 99久久er这里只有精品18| 丁香五月综合久久激情| 久久这里只有精品18| 亚洲国产综合久久天堂| 女人香蕉久久**毛片精品| 热re99久久6国产精品免费| 伊人久久大香线蕉AV一区二区| 国内精品久久人妻互换| 久久天天躁狠狠躁夜夜av浪潮 | 久久久精品人妻无码专区不卡| 亚洲欧美日韩久久精品第一区 | 一级a性色生活片久久无少妇一级婬片免费放| 亚洲AV无码久久精品成人| 大美女久久久久久j久久| 日韩欧美亚洲综合久久影院d3| 亚洲伊人久久精品影院| 亚洲国产成人久久一区WWW| 久久久久久av无码免费看大片|