• <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>

            Onway

            我是一只菜菜菜菜鳥...
            posts - 61, comments - 56, trackbacks - 0, articles - 34

            APUE第十一十二章 線程及其控制 筆記

            Posted on 2011-12-16 12:41 Onway 閱讀(488) 評論(0)  編輯 收藏 引用 所屬分類: 使用說明
            2011-12-5 第十一章 線程
            第一節 引言
            1,一個進程中的所有線程都可以訪問該進程的組成部件,如果文件按描述符和內存。
            2,無論何時,只要單個資源需要在多個用戶間共享,就必須處理一致性問題。

            第二節 線程概念
            1,通過為每種事件類型的處理分配單獨的線程,能夠簡化處理異步事件的代碼。
            2,多個線程自動地可以訪問相同的存儲地址空間和文件描述符。
            3,有些問題可以通過將其分解從而改善整個程序的吞吐量。
            4,交互的程序同樣可以通過使用多線程實現響應時間的改善。
            5,線程包含了表示進程內執行環境必需的信息,其中包括進程中標識線程的線程ID,一組寄存器值,棧,調度優先級和策略,信號屏蔽字,error變量以及線程私有數據。
            6,進程的所有信息對該進程的所有線程都是共享的,包括可執行的程序文本,程序的全局內存和堆內存,棧以及文件描述符。

            第三節 線程標識
            1,線程ID用pthread_t數據類型來表示。
            2,兩個線程ID進行比較:
            int pthread_equal(pthread_t tid1,pthread_t tid2);
            3,獲得自身的線程ID:
            pthread_t pthread_self(void);

            第四節 線程創建
            1,線程創建時并不能保證哪個線程先運行:是新創建的線程還是調用線程。
            2,新創建的線程可以訪問進程的地址空間,并且繼承調用線程的浮點環境和信號屏蔽字,但是該線程的未決信號集被清除。
            3,linux使用clone系統調用來實現pthread_create。clone系統調用創建子進程,這個子進程可以共享父進程一定數量的執行環境(如文件描述符和內存),這個數量是可配置。
            4,289頁pthread_create函數的聲明將void *(*start_rtn)(void*)漏了最后一個*號。

            第五節 線程終止
            1,如果進程的任一線程調用了exit,Exit或者_exit,那么整個進程就會終止。與此類似,如果信號的默認動作是終止進程,那么,把該信號發送給線程會終止整個進程。
            2,pthread_create和pthread_exit函數的無類型指針參數能傳遞的數值可以不止一個,該指針可以傳遞包含更復雜信息的結構的地址,但是注意這個結構所使用的內存在調用者完成調用以后仍然是有效的,否則就會出現無效或非法內存訪問。
            3,默認情況下,pthread_cancel函數會使得由tid標識的線程的行為表現為如同調用了參數為PTHREAD_CANCELED的pthread_exit函數,但是,線程可以選擇忽略取消方式或是控制取消方式。
            4,線程可以安排它退出時需要調用的函數。這樣的函數稱為線程清理處理程序。線程可以建立多個清理處理程序。處理程序記錄在棧中,也就是說它們的執行順序與他們注冊時的順序相反。
            5,這些函數(pthread_cleanup_push,pthread_cleanup_pop)有一個限制,由于它們可以實現為宏,所以必須在與線程相同的作用域中以匹配對的形式使用,pthread_cleanup_push的宏定義可包含字符{,在這種情況下對應的匹配字符}就要在pthread_cleanup_pop定義中出現。(不太懂)
            6,如果線程是通過從它的啟動例程中返回而終止的話,那么它的清理處理程序就不會被調用。
            7,297頁進程原語和線程原語的比較中,pthread_cleanup_push誤為pthread_cancel_push。

            第六節 線程同步
            1,當某個線程可以修改變量,而其他線程也可以讀取或者修改這個變量的時候,就需要對這些線程進行同步,以確保它們在訪問變量的存儲內容時不會訪問到無效的數值。
            2,對互斥量進行加鎖以后,任何其他試圖再次對互斥量加鎖的線程將會被阻塞直到當前線程釋放該互斥鎖。如果釋放互斥鎖的時候有多個線程阻塞,所有在該互斥鎖上的阻塞線程都會編程可運行狀態,第一個變為運行狀態的線程可以對互斥量加鎖,其他線程將會看到互斥鎖依然被鎖住,只能回去再次等待它重新變為可用。
            3,如果動態地分配互斥量,那么在釋放內存前需要調用pthread_mutex_destroy。
            4,如果線程試圖對同一個互斥量加鎖兩次或者兩個線程都在互相請求另一個線程擁有的資源,就會產生死鎖。
            5,可以通過小心地控制互斥量加鎖的順序來避免死鎖的發生。只有在一個線程試圖以與另一個線程相反的順序鎖住互斥量時,才可能出現死鎖。
            6,如果互斥鎖的順序難以安排的時候,可以采用另一種方法避免死鎖:先釋放占有的鎖,然后過一段時間再嘗試使用pthread_mutex_trylock加鎖。
            7,如果鎖的粒度太粗,就會出現很多線程阻塞等待相同的鎖,源自并發性的改善微乎其微。如果鎖的粒度太細,那么過多的鎖開銷會使系統性能受到影響,而且代碼變得相當復雜。
            8,302和304頁的程序中,在struct foo *foo_alloc(void)函數中fh[idx]=fp->f_next應為fh[idx]=fp。而且void foo_find(int id)這個函數即使id的對象存在,也不一定能找到該對象。這個兩個程序,按個人的理解,都是以散列表的元素作為單鏈表的頭指針。
            9,讀寫鎖可以有三種狀態:讀模式下加鎖狀態,寫模式下加鎖狀態,不加鎖狀態。一次只有一個線程可以占有寫模式的讀寫鎖,但是多個線程可以同時占有讀模式的讀寫鎖。
            10,讀寫鎖在讀加鎖狀態時,如果線程希望以寫模式對此鎖進行加鎖,它必須阻塞直到所有的線程釋放讀鎖。隨后的讀模式請求通常會被阻塞。
            11,如果pthread_rwlock_init為讀寫鎖分配了資源,pthread_rwlock_destroy將釋放這些資源。
            12,條件變量與互斥變量一起使用的時候,允許線程以無競爭的方式等待特定的條件發生。
            13,調用者把鎖住的互斥量傳遞給函數pthread_cond_wait,函數將調用線程放到等待條件的線程列表上,然后對互斥量解鎖,這兩個操作是原子操作。這樣就關閉了條件檢查和線程進入休眠狀態等待條件改變這兩個操作之間的時間通道(關鍵)。pthread_cond_wait返回時,互斥量再次被鎖住。
            14,從pthread_cond_wait或者pthread_cond_timedwait調用返回時3,線程需要重新計算條件,因為其他的線程可能已經在運行并改變了條件。
            15,調用pthread_cond_signal或者pthread_cond_broadcast,也稱為向線程或條件發送信號。必須注意一定要在改變條件狀態以后再給線程發信號。

            第七節 小結

            2011年12月9日 第十二章 線程控制
            第一節 引言

            第二節 線程限制
            1,線程限制宏
            PTHREAD_DESTRUCTOR_ITERATIONS 線程退出時候操作系統實現試圖銷毀線程私有數據的最大次數
            PTHREAD_KEYS_MAX 進程可以創建的鍵的最大數目
            PTHREAD_STACK_MIN 一個線程的棧可用的最小字節數
            PTHREAD_THREADS_MAX 進程可以創建的最大線程數
            2,雖然某些操作系統實現可能沒有提供訪問這些限制的方法,但這并不意味著這些限制不存在,它只是表明操作系統實現沒有提供使用sysconf訪問這些值的方法。

            第三節 線程屬性
            1,POSIX.1線程屬性
            detachstate 線程的分離狀態屬性
            guardsize 線程棧末尾的警戒緩沖區大小
            stackaddr 線程棧的最低地址
            stacksize 線程棧的大小(字節數)
            2,處于分離狀態的線程,退出后操作系統會回收它的資源。(問,這資源還歸進程擁有嗎?應該歸吧)
            3,pthread_attr_getstack和pthread_attr_setstack的參數stackaddr是指線程棧的最低地址,至于是開始位置還是結束位置,還要根據處理器的地址擴展方向來定。
            4,pthread_attr_setstacksize非常適用于希望改變線程棧大小,但又不想自己處理線程棧地址分配的情況。
            5,線程屬性guardsize控制著線程棧末尾之后用以避免棧溢出的擴展內存大小。
            6,只要pthread_attr_destroy調用失敗,都可能造成嚴重后果,最壞就是內存泄漏。
            7,對于遵循POSIX標準的操作系統來說,并不一定要支持線程棧屬性,但是對于遵循XSI擴展的系統,支持線程棧屬性就是必須的。
            8,并行是指無論從微觀還是宏觀上看,都是多個線程或者進程同時執行,而并發在微觀上不是同時執行的,只是把時間分成若干段,使多個進程或線程快速交替地執行。并行度越高,說明同時運行的任務數越多,如果相應的核數合適,可以提高整體的計算能力,充分發揮并行程序的效率。當然有時候也叫并發度,但是基本上都是在微觀上表示同時進行的線程/進程的個數。
            http://book.51cto.com/art/201009/224265.htm

            第四節 同步屬性
            1,互斥量的兩個屬性是:進程共享屬性和類型屬性。如果進程共享互斥量屬性被設置為PTHREAD_PROCESS_SHARED,從多個進程共享的內存區域中分配的互斥量就可以用于這些進程的同步。類型互斥量屬性控制著互斥量的特性。
            2,讀寫鎖支持的唯一屬性是進程共享屬性,該屬性與互斥量的進程共享屬性相同。
            3,條件變量也只支持進程共享屬性。
            ps:這一節看得很暈,已經超出了我的理解范圍了(12月10日)。

            第五節 重入
            1,如果一個函數在同一時刻可以被多個線程安全地調用,就稱該函數是線程安全的。
            2,支持線程安全函數的操作系統實現會在<unistd.h>中定義符號_POSIX_THREAD_SAFE_FUNCTIONS。
            3,操作系統實現支持線程安全函數這一特性時,對POSIX.1中的一些非線程安全函數,它會提供可替代的線程安全版本。
            4,如果一個函數對多個線程來說是可重入的,則說這個函數是線程安全的,但這并不能說明對信號處理程序來說該函數也是可重入的。如果函數對異步信號處理程序的重入也是安全的,那么就可以說函數是異步信號安全的。
            5,可以使用fflockfile和ftrylockfile獲取與給定FILE對象關聯的鎖。這個鎖是遞歸的。雖然這種鎖的具體實現并無規定,但要求所有操作FILE對象的標準I/O例程表現得就像它們內部調用了flockfile和funlockfile一樣。
            6,如果標準I/O例程都獲取它們各自的鎖,那么在一次一個字符的I/O操作時性能就會出現嚴重的下降。為了避免這種開銷,出現了不加鎖版本的基于字符的標準I/O例程。
            7,pthread函數并不能保證是異步信號安全的,所以不能把pthread函數用于其他函數,讓該函數成為異步信號安全的。

            第六節 線程私有數據
            1,設置線程私有數據的步驟:
            a,pthread_once保證pthread_key_create只被調用一次。
            b,pthread_key_create產生一個鍵。
            c,pthread_setspecific將動態分配的數據地址與鍵關聯起來。

            第七節 取消選項
            1,線程的可取消狀態和可取消類型這兩個屬性影響著線程在響應pthread_cancel函數調用時鎖呈現的行為。
            2,可取消類型分為異步取消和延遲取消,使用異步取消時,線程可以在任意時刻取消,而不是非得遇到取消點才能被取消。
            3,當線程處于延遲取消類型的情況下,可以調用pthread_setcancelstate修改它的可取消狀態。
            4,取消點是線程檢查是否被取消并按照取消請求進行動作的一個位置。
            5,當可取消狀態設置為PTHREAD_CANCEL_DISABLE時,對pthread_cancel的調用不會殺死進程,相反,取消請求對這個線程來說處于未決狀態。
            6,可以調用pthread_testcancel函數在程序中自己添加取消點。

            第八節 線程和信號
            1,每個線程都有自己的信號屏蔽字,但是信號的處理是進程中所有線程共享的。
            2,進程中的信號是傳遞到單個線程的。
            3,線程信號阻塞函數:pthread_sigmask。
            4,線程信號等待函數:sigwait。
            5,發送信號到線程:pthread_kill。
            6,鬧鐘定時器是進程資源,并且所有的線程共享相同的alarm。
            7,新建線程繼承了現有的信號屏蔽字。因為sigwait會解除信號的阻塞狀態,所以只有一個線程可以用于信號的接收。這使得對主線程進行編碼時不必擔心來自這些信號的中斷。

            第九節 線程和fork
            1,如果父進程包含多個線程,子進程在fork返回以后,如果緊接著不是馬上調用exec的話,就需要清理鎖狀態。
            2,要清除鎖狀態,可以調用pthread_atfork函數建立fork處理程序。

            第十節 線程和I/O
            1,可以使用pwrite和pread來解決并發線程對同一文件進行寫操作的問題。

            第十一節 小結


            ps:只是每天晚上看一點,感覺還是比較急了,而且這些東西目前還用不上,代碼也沒寫過。就算看個概念吧。
            九九久久99综合一区二区| 亚洲欧美久久久久9999| 久久亚洲sm情趣捆绑调教| 亚洲七七久久精品中文国产 | 久久激情亚洲精品无码?V| 合区精品久久久中文字幕一区| 久久天天婷婷五月俺也去| 狠狠色丁香久久婷婷综合| 精品久久久久久国产91| 日本国产精品久久| 97久久精品无码一区二区| 久久久久亚洲AV成人网人人网站| 无码人妻精品一区二区三区久久久| 2022年国产精品久久久久| 热RE99久久精品国产66热| 伊人色综合久久天天人守人婷| 色欲综合久久躁天天躁| 久久久老熟女一区二区三区| 久久精品无码专区免费| jizzjizz国产精品久久| 久久综合亚洲色HEZYO社区| 青青青青久久精品国产 | 久久久久亚洲AV成人网人人软件| 久久婷婷人人澡人人爽人人爱 | 久久se这里只有精品| 久久亚洲精品中文字幕| 性做久久久久久久久浪潮| 久久精品国产99国产精品澳门| 亚洲中文字幕无码一久久区| 久久精品国产99久久丝袜| 青青国产成人久久91网| 久久国产精品无码HDAV| 伊人久久大香线蕉亚洲| 中文字幕精品久久| 日本久久中文字幕| 久久久久人妻精品一区三寸蜜桃 | 久久久老熟女一区二区三区| 一本大道久久东京热无码AV | 欧美久久久久久精选9999| 久久99精品综合国产首页| 国产亚洲精久久久久久无码|