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

            線程函數
            int pthread_equal(pthread_t tid1, pthread_t tid2)
            pthread_t pthread_self(void)

            int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr
                 void* (*start_rtn)(void), void* restrict arg)

            thread被創建的時候會繼承調用線程的浮點環境和信號屏蔽字,但是該線程的未決信號集將會被清楚,
            清除未決信號集這件事情應該是沒有疑問的,在thread創建之前pending住的信號,不應該deliver給下一個
            Ps: 線程的浮點環境指的是啥? 看來以后我應該去注意下浮點數的運算原理。

            pthread相關的函數會直接返回錯誤碼,而不會和一些system call一樣,置全局errno,兩種方式都有好處,一個可以講返回值
            帶回的錯誤代碼集中起來,范圍縮小;另外一個非常方便,關鍵點在于這一類共用errno的是否真的異常是可以共用的。

            pthread_create返回之前有可能新的線程就已經開始run了

            啟動函數 void* (*start_rtn)(void)

            可以通過return給回來,也可以通過pthread_exit給
            這個會存在一個地方
            通過pthread_join(tid, void**)取回來

            這里join的和java join是一樣的功能

            如果這個東西是一個很大的東西:),那么放到heap是最好的選擇,不要放到stack上了,不然線程返回這東西就沒了,join取到的內存地址就變成一個無效的了,SIGSEGV就會被發出來

            pthread_cancel,同一個進程可以call,提出請求終止線程

            pthread_cleanup_push
            pthread_cleanup_pop

            線程分離,這樣子線程終止后可以釋放一些資源,而不用一定要其他人來join
            方法有兩種,新建的時候加上分離屬性
                pthread_attr_init (&attr);
                pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
                ret = pthread_create(&s_tid_dispatch, &attr, eventLoop, NULL);

            或者call pthread_detach(pthread_t tid)

            線程互斥與同步

            typedef struct
            {
                
            int volatile value;
            }
             pthread_mutex_t;

            多注意volatile變量,這個東西理論上就是讓編譯器不要做優化,不要cache volatile類型的變量,
            每次都去內存地址中拿,而不是寄存器/高速緩存副本,這種變量極容易被編譯器不知道的人改變,例如其他線程。

            靜態初始化:
            #define  PTHREAD_MUTEX_INITIALIZER             {0}
            #define  PTHREAD_RECURSIVE_MUTEX_INITIALIZER   {0x4000}
            #define  PTHREAD_ERRORCHECK_MUTEX_INITIALIZER  {0x8000}
            所謂的動態初始化
            pthread_mutex_init; pthread_mutex_destroy

            然后就是一些pthread mutex的基本處理函數了
            lock,unlock
            trylock;

            這個trylock需要好好理解下,嘗試獲取lock,如果OK,那么lock他然后 return 0; 否則也不會suspend住,而是直接返回EBUSY

            pthread_mutex_destroy, 會先去try lock,然后處理掉這個mutex的值。

            這里稍微提一下

            int pthread_mutex_trylock(pthread_mutex_t *mutex)
            {
                
            int mtype, tid, oldv, shared;

                
            if (__unlikely(mutex == NULL))
                    
            return EINVAL;

                mtype  
            = (mutex->value & MUTEX_TYPE_MASK);
                shared 
            = (mutex->value & MUTEX_SHARED_MASK);

                
            /* Handle common case first */
                
            if ( __likely(mtype == MUTEX_TYPE_NORMAL) )
                
            {
                    
            if (__atomic_cmpxchg(shared|0, shared|1&mutex->value) == 0{
                        ANDROID_MEMBAR_FULL();
                        
            return 0;
                    }


                    
            return EBUSY;
                }




            __likely/__unlikely函數用來告訴編譯器優化代碼,類似if else中最有可能or最沒有可能發生的Case

            mutex就有deadlock的問題,單線程,如果有代碼重入重復獲取鎖就會deadlock,因為你走不到你unlock的地方去;另外
            常見的deadlock就是lock比較多,又沒有設計好順序,這個應該從業務邏輯上就應該定義好,當然有時候有的人用的時候or改代碼的時候
            并沒有理清這些lock的關系,是否有dependency,比較難通過借用一些編譯系統來Cover住,然后改完就有bug。

            然后還有一種需要設計好的是鎖的粒度
            太粗太細都不好
            粒度太粗,lock住的東西太多,很多線程都要等lock,最后這個東西會演變成一個串行的東西
            粒度太細,lock又變的太多,不停的需要lock/unlock,performance就會變差。
            目前看到的Android上的很多lock都太粗。

            rw鎖 ->讀寫鎖
            基本理念就是讀不會影響臨界區發生變化
            所以讀模式的rw lock可以多個人占用,寫模式的rw lock時能被一個線程lock

            只要有寫模式lock請求,那么后面的讀模式lock請求一般實現是都會被Suspend住,不然因為讀模式下,可以重復lock,如果不
            suspend,那么寫模式的lock請求有可能永遠得不到相應。
            rw鎖一般用在 read比 write行為多的多的場景,允許多線程并發去讀,單一線程去寫。

            然后會想到spinlock,可以去網上search看下基本概念,spinlock一般在SMP架構下會比較有效果。

            mutex是一種同步機制or講這是一種互斥機制 -> Java synchronize
            還一種就是條件變量 condition.. -> wait/notify

            這里有段話很好
            條件變量給多個線程提供了一個回合的場所,條件變量與互斥量一起使用的時候,允許線程以無競爭方式等待特定的條件發生。

            作業:
            1.線程之間傳遞數據不要用stack變量,用放到下面這些地方的變量就好,RW/RO/ZI/Heap就沒事了
            4.
            現在一般都是這樣

                pthread_mutex_lock(&s_startupMutex);

                s_started = 1;
                pthread_cond_broadcast(&s_startupCond);

                pthread_mutex_unlock(&s_startupMutex);

            會在broadcast后才unlock
            否則有比較高的概率,unlock后,被其他線程將條件改掉,這個時候broadcast出去就沒有意義了。
            但是這種也有可能會被另外一個線程,并非wait在那里的線程改變條件值

            所以 pthread_cond_wait 返回并不意味著條件一定為真了
            最好是always check條件
            類似這種
                while (s_started == 0) {
                    pthread_cond_wait(&s_startupCond, &s_startupMutex);
                }

            posted on 2013-06-03 17:03 Torres 閱讀(205) 評論(0)  編輯 收藏 引用 所屬分類: APUE
            久久久久亚洲AV无码永不| 久久久久久久尹人综合网亚洲| 97久久久精品综合88久久| 国产精品久久久久久久| 久久久久国产精品嫩草影院 | 人妻无码αv中文字幕久久| 色妞色综合久久夜夜| 久久九九青青国产精品| 99久久做夜夜爱天天做精品| 奇米影视7777久久精品| 久久国产视频99电影| 久久亚洲AV成人出白浆无码国产| 久久美女网站免费| 伊人久久精品无码二区麻豆| 777久久精品一区二区三区无码 | 亚洲午夜久久影院| 久久久久久免费视频| 91精品国产91久久久久久| 国产精品久久久久久久久久影院 | 久久国产精品视频| 久久婷婷五月综合97色一本一本| 国产真实乱对白精彩久久| 91精品国产91久久综合| 久久精品国产亚洲AV忘忧草18 | 久久久久国产精品麻豆AR影院| 久久久免费精品re6| 亚洲七七久久精品中文国产| 久久国产视频网| 人人狠狠综合久久亚洲88| 久久发布国产伦子伦精品| 国产激情久久久久久熟女老人| 欧洲国产伦久久久久久久| 久久人人爽人人澡人人高潮AV | 无码人妻久久一区二区三区| 欧美与黑人午夜性猛交久久久 | 91性高湖久久久久| 99久久久国产精品免费无卡顿| 婷婷久久久亚洲欧洲日产国码AV| 中文国产成人精品久久亚洲精品AⅤ无码精品 | 色综合合久久天天综合绕视看| 精品久久久久久国产潘金莲 |