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

            T9的空間

            You will never walk alone!

              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
              69 隨筆 :: 0 文章 :: 28 評論 :: 0 Trackbacks

            線程控制

            APUE講的destroy會free空間,這件事情看起來不太對,也許是Base on實現
            起碼我看到的實現是沒有做這件事情的。

             

            int pthread_attr_init(pthread_attr_t * attr)
            {
                
            *attr = gDefaultPthreadAttr;
                
            return 0;
            }


            int pthread_attr_destroy(pthread_attr_t * attr)
            {
                memset(attr, 
            0x42sizeof(pthread_attr_t));
                
            return 0;
            }


            Attribution有下面這些。

             

            typedef struct
            {
                uint32_t flags;
                
            void * stack_base;
                size_t stack_size;
                size_t guard_size;
                int32_t sched_policy;
                int32_t sched_priority;
            }
             pthread_attr_t;

            我們可以用malloc和mmap給Thread分配stack,指定stack大小和位置(低地址)

            mutex屬性
            兩個東西
            1.進程共享屬性,PTHREAD_PROCESS_PRIVATE or SHARED
            意思是說如果這個Mutex是分配在兩個進程共享的memory,然后設置為shared mutex就可以用于進程同步
            2.類型屬性,normal;errorcheck;recurive
            意思是定義Mutex本身的特性,這里更正下前面那章提到的錯誤
            只有normal的mutex才會在再次加鎖時發生deadlock
            errorcheck的會直接返回錯誤
            recurive本身就允許,會有計數

            rw lock和condition屬性
            只支持第一個

            TLS變量
            先看下TLS的位置

             * +---------------------------+
             
            * |     pthread_internal_t    |
             
            * +---------------------------+
             
            * |                           |
             
            * |          TLS area         |
             
            * |                           |
             
            * +---------------------------+
             
            * |                           |
             
            * .                           .
             
            * .         stack area        .
             
            * .                           .
             
            * |                           |
             
            * +---------------------------+
             
            * |         guard page        |
             
            * +---------------------------+

            pthread_internal_t是記錄線程自己本身的一些屬性的變量,guard page就是線程attr上設置的防止棧溢出的擴展內存

            創建TLS變量的方法
            1.創建Key,這個Key是這個Process中所有Thread可以共享訪問的,然后每個Thread自己去關聯自己的Thread Local變量
            int pthread_key_create(pthread_key_t *keyp, void (*destructor)(void*))
            創建key的時候需要保證唯一調用,也就是不會有兩個Thread同時調用,然后發生一些base on實現的不確定的結果,可以使用pthread_once

            pthread_once的實現很簡單,用mutex做互斥量保證pthread_once_t的訪問,然后利用pthread_once_t做flag來調用init_routine

            int  pthread_once( pthread_once_t*  once_control,  void (*init_routine)(void) )
            {
                
            static pthread_mutex_t   once_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
                
            volatile pthread_once_t* ocptr = once_control;

                pthread_once_t tmp 
            = *ocptr;
                ANDROID_MEMBAR_FULL();
                
            if (tmp == PTHREAD_ONCE_INIT) {
                    pthread_mutex_lock( 
            &once_lock );
                    
            if (*ocptr == PTHREAD_ONCE_INIT) {
                        (
            *init_routine)();
                        ANDROID_MEMBAR_FULL();
                        
            *ocptr = ~PTHREAD_ONCE_INIT;
                    }

                    pthread_mutex_unlock( 
            &once_lock );
                }

                
            return 0;
            }

            所以這個pthread_once_t必須是全局or靜態變量
            pthread_once最常用的case除了拿到TLS key外,init函數經常會使用這個,避免多線程同時調用。

            然后就是thread cancel
            Android Bionic庫沒有實現 pthread_setcancelstate(int state, int* oldstate)以及pthread_cancel()
            這里thread的取消,有些是取消不掉的,例如一些blocking call,所有的取消均是需要設定一些取消點的,

            有人有專門針對Android沒有Thread Cancel來想辦法
            基本就是thread signal,在signal handler中去call pthread_exit();
            or用PIPE在多路復用中break出來
            http://blog.csdn.net/langresser/article/details/8531112

            如果信號與硬件故障or計時器超時相關,那么信號會發送到引起事件的該線程中去,其他信號會發送到任意一個線程。
            這里是說的POSIX線程模型,一般的信號都會發送給進程中沒有阻塞該信號的某個線程。APUE講的某個沒有阻塞該信號的線程,其實有點模糊。

            但是Linux的實現不一樣,linux的thread是clone出來的,就是共享資源的獨立進程,這樣子其實蠻自然的,也不容易復雜。
            linux中,有可能線程就不會注意到該信號,這樣講也有點模糊,總之終端驅動程序的信號會將信號通知到進程組,這樣子所有的thread就會都收到信號
            如果你不想所有的線程都去關心信號,那么可以使用一個專門處理信號的線程
            先將其他線程的signal都pthread_sigmask SIG_BLOCK掉,然后使用sigwait在特定的線程來等
            pthread_sigmask和sigprocmask很像

            thread與fork
            fork后的子進程會繼承mutex, rw lock, condition的狀態
            但是子進程中只會存在一個線程,也就是那個調用fork的線程的副本,有個復雜的事情是關于上面繼承下來的那些東西,子進程由于只有一個線程,沒辦法知道
            上面那三個東西的具體狀態,需要有個清理鎖的動作 -->pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void))
            我目前不知道這個東西的使用場景,而且不容易控制。
            因為一般如果我們fork后都會接execu,這樣地址空間就會改變,那么這些繼承的東西就沒用了。

            然后有談一點關于線程IO的東西
            pwrite/pread
            也就是原子的進行lseek和r/w,但是這個并不能保證大家常見的沖突問題,也就是一個thread在寫另外一個要讀,所以這兩個東西并不能解決同步的問題。

            作業:
            12.3 理論上函數開始時屏蔽所有信號,函數結束時恢復,是可以做到異步信號安全的。如果你只是屏蔽一些信號,那么沒辦法做到,因為如果有其他信號進來,你call的函數里面有一些不可重入的函數,同樣不能保證是異步安全的。

            12.5 fork可以在拿來執行可執行程序,現在應該就這一個Case。

            posted on 2013-06-04 15:41 Torres 閱讀(277) 評論(0)  編輯 收藏 引用 所屬分類: APUE
            久久精品国产精品亚洲精品| 久久这里只有精品首页| 久久亚洲精品中文字幕三区| 久久久久无码专区亚洲av| 婷婷五月深深久久精品| 久久久久久久久久久免费精品| 久久人搡人人玩人妻精品首页| 久久婷婷久久一区二区三区| 久久99精品久久久久久9蜜桃| 久久66热人妻偷产精品9| 亚洲欧美一级久久精品| 国产精品免费看久久久香蕉| 99精品久久精品| 久久人人爽人人爽人人片av高请| 怡红院日本一道日本久久 | 国产精品成人精品久久久| 国产午夜电影久久| 久久久久久无码Av成人影院| 午夜精品久久久久久久| 狠狠色伊人久久精品综合网| 国产V综合V亚洲欧美久久| 久久久久免费精品国产| 久久综合五月丁香久久激情| 97久久久久人妻精品专区| 午夜精品久久久久| 久久婷婷色综合一区二区| 久久综合九色综合精品| 99久久久精品| 精品无码久久久久久尤物| 亚洲精品国产美女久久久| 久久婷婷色香五月综合激情| 午夜精品久久久久成人| 久久99久久99精品免视看动漫 | 亚洲人成网亚洲欧洲无码久久| 99久久这里只精品国产免费| 久久99精品久久久久久水蜜桃 | 亚洲国产成人久久一区久久| 久久精品一区二区影院| 日韩中文久久| 中文国产成人精品久久亚洲精品AⅤ无码精品| 中文精品久久久久国产网址 |