線程同步機制:http://www.cnblogs.com/zheng39562/p/4270019.htmlhtml
1、基礎知識安全
1:基礎知識。多線程
1,線程須要的信息有:線程ID,寄存器,棧,調度優先級和策略,信號屏蔽字,errno變量和線程私有數據。異步
2,進程的全部信息對全部線程都是共享的。函數
3,是否支持有多線程有如下兩種方式測試:測試
1)編譯時肯定:#ifdef _POSIX_THREADSspa
2)運行時肯定:sysconf函數調用 _SC_THREADS 經常使用。線程
4,線程ID。指針
1)一個進程中,線程ID具備惟一性。線程ID依賴與進程後,纔有意義。rest
2)線程ID表示類型:pthread_t類型
5,變量增量操做的步驟:
1)變量值從 內存單元 讀入 寄存器。
2)寄存器中對變量進行修改。
3)將變量值 寫回 內存單元
4)因此,多個線程試圖同時修改同一變量時,須要同步。
6,進程資源和線程的關係:
1)每一個線程都有本身的信號屏蔽字。但,信號處理是全部線程共享的。因此,線程對信號的處理會影響全部線程。
2)鬧鐘定時是進程資源。全部線程共享使用。
3)pread / pwrite 函數在多線程讀寫比較適用。由於其能夠保存多個線程的讀寫偏移量,從而保證不會被覆蓋。
2:線程建立和終止。
1,線程建立。
1)並不能肯定哪一個線程先運行(和子進程建立相似)。
2)建立函數create失敗後,一般會返回錯誤碼。
2,線程終止。
1)任意線程調用 exit, _Exit, _exit函數都會使進程終止。(因此不可使用此方式終止單個線程)
2)從啓動例程返回。返回值時線程退出碼。
3)能夠被同進程中的其餘線程取消。
4)線程調用pthread_exit函數。
3:線程的數據和安全
1,線程安全:一個函數在相同時間點能夠被多個線程安全地調用。
1)當一個函數是可重入時,那就是線程安全的。
2)異步信號安全。
2,可重入函數。
1)當處理信號中斷時,部分函數可能更改信息,致使中斷處理結束後,沒法正確的從中斷點繼續執行程序(信息錯位)。
2)可重入函數保證再中斷期間調用這些函數,不會致使信息錯位。
3)可重入函數又被稱爲異步信號安全的函數。
3,線程私有數據:具體操做見函數。
5:進程和線程功能/函數對應表
進程原語 | 線程原語 | 描述 |
fork |
pthread_create | 建立新的控制流 |
exit | pthread_exit | 從先有控制流中退出 |
waitpid | pthread_join | 從控制流中獲得退出狀態 |
atexit | pthread_cancel_push | 註冊在退出控制流時的調用的函數 |
getpid | pthread_self | 獲取控制流的ID |
abort | pthread_cancel | 請求控制流的非正常退出。 |
2、相關函數。
1:線程操做函數。
1 比較線程ID大小。 int pthread_equal( pthread_t tid1, pthread_t tid2 ) 2 獲取自身線程ID。 pthread_t pthread_self( void ); 3 建立線程。 int pthread_create( pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg); // 1 參數arg用於定製各類不一樣的線程屬性 4 線程終止。 void pthread_exit( void *rval_ptr ); 5 得到線程退出狀態。 int pthread_join( pthread_t thread, void **rval_ptr ); // 1 參數rval_ptr包含返回碼。 6 取消其餘線程(同進程中使用) int pthread_cancel( pthread_t tid ); // 1 僅僅提出請求。並不強制終止。 7 線程清理處理程序(相似進程的atexit)。 void pthread_cleanup_push( void (*rtn)(void *), void *arg); void pthread_cleanup_pop( int execute ); // 1 參數execute=0時,清理函數將不被調用。 // 2 每次調用pop函數時,都出刪除上一個push的清理程序。 // 3 這些函數被實現爲宏。須要注意{}等匹配。 // 4 清理程序的註冊和執行順序相反。 8 分離線程。 int pthread_detach( pthread_t tid ); 9 清除子進程的鎖 int pthread_atfork( void (*prepare)(void), void (*parent)(void), void (*child)(void) ); // 1 註冊和執行順序相反。 10 上述函數中。部分無類型指針,能夠傳遞的值有不少,甚至能夠時一個結構體。
2,線程屬性 相關函數。
1 線程屬性 初始化 和 類析構函數 int pthread_attr_init( pthread_attr_t *attr ); int pthread_attr_destroy( pthread_attr_t *attr ); 2 獲取/設置 分離狀態。 int pthread_attr_getdetachstats( const pthread_attr_t *restrict attr, int *detachstate ); int pthread_attr_setdetachstats( pthread_attr_t *attr, int *detachstate ); // 1 參數detachstate只有兩個值:PTHREAD_CREATE_ DETACHED/JOINABLE. 3 獲取/設置 線程棧屬性 stackaddr。 int pthread_attr_getstack( const pthread_attr_t *restrict attr, void **restrict stackaddr, size_t *restrict stacksize ); int pthread_attr_setstack( pthread_attr_t *attr, void *stackaddr, size_t stacksize ); // 1 stackaddr線程屬性定義爲棧的最低內存地址。是起始位置,仍是結尾位置取決於棧的發展方向。一般是結尾(棧由高向低) 4 獲取/設置 棧大小屬性 stacksize。 int pthread_attr_getstacksize( const pthread_attr_t *restrict attr, size_t *restrict stacksize ); int pthread_attr_setstacksize( pthread_attr_t *attr, size_t stacksize ); 5 獲取/設置 線程棧末尾緩衝區大小 guardsize。 int pthread_attr_getguardsize( const pthread_attr_t *restrict attr, size_t *restrict guardsize ); int pthread_attr_setguardsize( pthread_attr_t *attr, size_t guardsize );
3:線程私有數據。
1 建立一個鍵 int pthread_key_create( pthread_key_t *keyp, void (*destructor)(void *)); // 1 能夠指定一個析構函數(第二個參數) // 2 每一個線程的鍵的獨立的:即相同的KEY在不一樣線程中表示不一樣的數據。 2 取消一個鍵和特定線程的關聯。 int pthread_key_delete( pthread_key_t key ); // 1 不激活關聯的析構函數。 3 使一個鍵只被調用一次:使不一樣線程擁有不一樣的鍵。 int pthread_once( pthread_once_t *initflag, void (*initfn)(void)); 4 獲取/設置 鍵內數據。 void *pthread_getspecific( pthread_key_t key ); int pthread_setspecific( pthread_key_t key , const void *value );
4:特殊線程屬性:可取消狀態 和 可取消類型。
1 設置 可取消狀態 int pthread_setcancelstate( int state, int *oldstate ); // 1 取消狀態有兩種: PTHREAD_CANCEL_ ENABLE/DISABLE 2 設置 本身的取消點。 void pthread_testcancel( void ); // 1 取消狀態做用:取消請求發出後,會在下一個取消點進行取消操做(我的理解退出線程)。 3 修改取消類型。 int pthread_setcanceltype( int type, int *oldtype )
5:線程和信號
1 線程阻止信號發送 int pthread_sigmask( int how, const sigset_t *restrict set, sigset_t *restrict oset ); 2 等待信號。 int sigwait( const sigset_t *restrict set, int *restrict signop ); // 1 參數set指定線程等待的信號集。 // 2 參數signop 包含發送信號的數量。 // 3 在使用函數前,必須先阻塞它等待的信號。(參數一) // 4 函數在執行時,會取消信號集的阻塞狀態。 3 發送信號給線程。 int pthread_kill( pthread_t thread, int signo ); // 1 參數signo傳遞0,能夠檢查線程是否存在
3、