• <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 閱讀(206) 評論(0)  編輯 收藏 引用 所屬分類: APUE
            国产叼嘿久久精品久久| 日韩精品久久久久久| 精品国产青草久久久久福利 | 久久国产综合精品五月天| 久久久久夜夜夜精品国产| 亚洲国产精品无码久久久蜜芽| 性欧美大战久久久久久久| 亚洲精品白浆高清久久久久久| 欧美一区二区三区久久综合| 亚洲国产成人久久精品动漫| 色妞色综合久久夜夜| 久久这里只有精品首页| 国产精品欧美久久久久天天影视 | 伊人久久精品无码av一区| 97超级碰碰碰久久久久| 亚洲Av无码国产情品久久| 国产精品无码久久久久久| 亚洲午夜久久久| 国内精品久久久久久久涩爱| 国产精品免费福利久久| 久久久精品国产| 久久久噜噜噜久久中文字幕色伊伊| 日产精品久久久一区二区| 久久青青草原精品国产不卡| AAA级久久久精品无码片| 伊人久久大香线蕉综合5g| 久久99国产精品久久| 欧美精品久久久久久久自慰| 国产精品久久久久蜜芽| 日韩久久无码免费毛片软件| 国产成人无码精品久久久免费| 久久久久久久人妻无码中文字幕爆| 亚洲国产成人久久一区WWW| 国产无套内射久久久国产| 97久久香蕉国产线看观看| 久久久久久久人妻无码中文字幕爆| 色综合久久无码五十路人妻| 狠狠精品久久久无码中文字幕| 精品久久久久成人码免费动漫| 无码任你躁久久久久久久| 久久无码高潮喷水|