1、基礎知識。函數
1:線程同步機制:互斥量,讀寫鎖,條件變量,自旋鎖,屏障。spa
1,互斥量:每一個進程訪問被互斥量保護的資源時,都須要先對互斥量進行判斷。操作系統
1)互斥量重要屬性:進程共享屬性,健壯屬性,類型屬性。線程
2)部分系統 不支持 進程共享屬性rest
3)對互斥量重複加鎖會致使死鎖。code
2,讀寫鎖。blog
1)讀寫鎖有3種狀態:讀模式加鎖,寫模式加鎖,未加鎖。遞歸
1-寫加鎖模式:任何加鎖都會被阻塞。隊列
2-讀加鎖模式:讀模式加鎖的任何線程均可以獲得訪問權,同時添加一個讀模式鎖。但,寫模式加鎖會被阻塞。進程
3-在讀模式下,線程試圖寫加鎖,會阻塞:1 線程自己 和 2 以後的讀模式。保證寫模式不會被一指阻塞。
2)遞歸鎖可能很難處理,只有在無其餘反感時,才考慮。
3)讀寫鎖支持的惟一屬性時:進程共享屬性。
3,條件變量:條件變量是線程的另一種同步機制。它自己由互斥量保護。線程在改變條件狀態以前必須首先鎖住互斥量。
1)條件變量支持屬性:進程共享屬性 和 時鐘屬性。
4,自旋鎖。
1)和互斥量相似。不一樣點在於:獲取鎖以前,線程一直處於 忙等(自旋)阻塞狀態。(互斥量使用休眠阻塞)
2)只能用於:鎖持有時間短,線程不喜歡在從新調度上花費太多成本。
3)在非搶佔式內核中很是有用:由於它會阻塞中斷。這樣中斷處理程序就不會讓系統陷入死鎖狀態。
5,屏障。
1)相似於里程碑:用戶協調多個線程並行工做的同步機制。它容許每一個線程等待,直到全部合做的線程都到達某一個點(里程碑)。
2)屏障屬性只有 進程共享屬性。
3)PTHREAD_PROCESS_SHARED(多進程共享) 和 PTHREAD_PROCESS_PROVATE(單進程,不共享)
2、相關函數。
1:信號。
1 發送信號 int kill(pid_t pid, int signo ); 發送信號給進程/進程組 // 1 參數pid:>0 ID=pid的進程中;0 同進程組的全部進程;<0 進程組ID==pid絕對值 的進程組中;-1 全部可以發送的進程。 int raise( int signo ); 發送信號給自身。 2 信號集處理函數 int sigemptyset( sigset_t *set ); int sigfillset( sigset_t *set ); int sigaddset( sigset_t *set, int signo ); int sigdelset( sigset_t *set, int signo ); int sigismember( sigset_t *set, int signo ); 3 信號屏蔽字。 int sigprocmask( int how, const sigset_t *restrict set, sigset_t *restrict oset ); // 檢測和更改,或同時檢測+更改進程的信號屏蔽字。 int sigpending( sigset_t *set ); // 返回一個信號集。 int sigaction( int signo, const struct sigaction *restrict act, struct sigaction *restrict oact ); // 檢測/修改與指定信號相關聯的處理動做 int sigsupend( const sigset_t *sigmask ); // 做用:經過參數設置信號屏蔽字。 4 信號跳轉函數。 int sigsetjmp( sigjmp_buf env, int savemask ); // 設置信號跳轉點。 void siglongjmp( sigjmp_buf env, int val ); // 執行跳轉操做,參數val爲跳轉點返回值。 5 異常終止函數。 void abort( void ); // 使程序異常終止。 // 1 使用此函數,會將SIGABRT信號發送給調用進程。進程不能忽略此信號 // 2 發送SIGABRT信號,進程能夠先執行清理操做,而後再終止進程。 6 線程休眠函數。 unsigned int sleep( unsigned int seconds ); int nanosleep( const struct timespec *reqtp, struct timespec *remtp ); // 提供納妙級精度。 int clock_nanosleep( clockid_t clock_id, int flags, const struct timespec *reqtp, struct timespec *remtp ); // 多系統時鐘狀況下,使用相對於特定時鐘的延遲時間來掛起調用進程。 int sigqueue( pid_t pid, int signo, const union sigval value ); // 信號隊列,能夠將信號發送到一個進程的信號隊列中。部分操做系統支持此功能。 // 1 可能使休眠終止的情形:調用進程捕捉到一個信號並從信號處理程序返回。
2:互斥量。
1 初始化。 PTHREAD_MUTEX_INITIALIZER //靜態分配方式。 int pthread_mutex_init( pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr ); // 動態分配內存方式 // 1 使用默認初始化,參數attr設置爲NULL。 2 類析構函數(釋放內存前當用)。 int pthread_mutex_destroy( pthread_mutex_t *mutex ); 3 加鎖,嘗試性加鎖,超時鎖,解鎖 int pthread_mutex_lock( pthread_mutex_t *mutex ); // 若是已經加鎖的互斥量,會阻塞線程,直到互斥量解鎖。 int pthread_mutex_trylock( pthread_mutex_t *mutex ); //trylock嘗試上鎖失敗後,會返回EBUSY。而不會阻塞。 int pthread_mutex_timedlock( pthread_mutex_t *restrict mutex, const struct timespec *restrict tsptr ); //超時返回:ETIMEDOUT int pthread_mutex_unlock( pthread_mutex_t *mutex ); // 1 若是線程試圖對同一互斥量加鎖兩次,則線程會陷入死鎖狀態。。 // 2 超時鎖參數tsptr 表示是 絕對時間(即具體時間點,而不是時間段)
3:互斥量屬性相關函數。
1 初始化和類析構函數。 int pthread_mutexattr_init( pthread_mutexattr_t *attr ); int pthread_mutexattr_destroy( pthread_mutexattr_t *attr ); 2 獲取/設置 進程共享屬性。 int pthread_mutexattr_getshared( const pthread_mutexattr_t *restrict attr, int *restrict pshared ); int pthread_mutexattr_setshared( pthread_mutexattr_t *attr, int *pshared ); 3 獲取/設置 健壯屬性 int pthread_mutexattr_getrobust( const pthread_mutexattr_t *restrict attr, int *restrict robust ); int pthread_mutexattr_setrobust( pthread_mutexattr_t *attr, int *robust ); 4 解鎖前,使屬性狀態統一。 int pthread_mutexattr_consistent( pthead_mutex_t *mutex ); 5 獲取/設置 類型屬性 int pthread_mutexattr_gettype( const pthread_mutexattr_t *restrict attr, int *restrict type ); int pthread_mutexattr_settype( pthread_mutexattr_t *attr, int *type );
4:讀寫鎖
1 初始化。 int pthread_rwlock_init( pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr ); // 1 使用默認初始化,參數attr設置爲NULL。 2 類析構函數(釋放內存前當用)。 int pthread_rwlock_destroy( pthread_rwlock_t *rwlock ); 3 讀加鎖,嘗試讀,超時版讀,寫加鎖,嘗試寫,超時版寫,解鎖。 int pthread_rwlock_rdlock( pthread_rwlock_t *rwlock ); int pthread_rwlock_tryrdlock( pthread_rwlock_t *rwlock ); int pthread_rwlock_timedrdlock( pthread_rwlock_t *rwlock, const struct timespec *restrict tsptr ); int pthread_rwlock_wrlock( pthread_rwlock_t *rwlock ); int pthread_rwlock_trywrlock( pthread_rwlock_t *rwlock ); int pthread_rwlock_timedwrlock( pthread_rwlock_t *rwlock, const struct timespec *restrict tsptr ); int pthread_rwlock_unlock( pthread_rwlock_t *rwlock ); // 1 讀加鎖有次數限制。 // 2 嘗試版本,出錯返回:EBUSY。 // 3 超時版本,出錯返回:ETIMEDOUT。超時時間 爲 絕對時間。 4 獲取/設置 進程共享屬性。 int pthread_rwlockattr_getpshared( const pthread_rwlockattr_t *restrict attr, int *restrict pshared ); int pthread_rwlockattr_setpshared( pthread_rwlockattr_t *attr, int *pshared );
5:條件變量。
1 初始化。 int pthread_cond_init( pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr ); // 1 使用默認初始化,參數attr設置爲NULL。 2 類析構函數(釋放內存前當用)。 int pthread_cond_destroy( pthread_cond_t *cond ); 3 等待條件爲真,超時版本。 int pthread_cond_wait( pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex ); //此函數能夠保證線程必定能夠進入條件等待隊列中。 int pthread_cond_timedwait( pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict tsptr ); // 1 將加鎖互斥量傳入,而後將調用線程放入條件隊列中,再解鎖互斥量。等wait函數返回後,互斥量再加鎖。 // 2 超時返回:ETIMEDOUT 4 喚醒等待條件的線程。 int pthread_cond_signal( pthread_cond_t *cond ); // 最少喚醒一個線程。 int pthread_cond_broadcast( pthread_cond_t *cond ); // 喚醒所有線程。 // 1 須要注意:要等條件狀態改變之後,在使用這兩個函數!!! 5 條件屬性的初始化和類析構函數。 int pthread_condattr_init( pthread_condattr_t *attr ); int pthread_condattr_destroy( pthread_condattr_t *attr ); 6 獲取/設置 進程共享屬性。 int pthread_condattr_getpshared( const pthread_condattr_t *restrict attr, int *restrict pshared ); int pthread_condattr_setpshared( pthread_condattr_t *attr, int *pshared ); 7 獲取/設置 時鐘屬性。 int pthread_condattr_getclock( const pthread_condattr_t *restrict attr, clockid)t *restrict clock_id ); int pthread_condattr_setclock( pthread_condattr_t *attr, clockid)t *clock_id );
6:自旋鎖。
1 初始化,類析構函數(釋放內存前使用) int pthread_spin_init( pthread_spinlock_t *lock, int pshared ); int pthread_spin_destroy( pthread_spinlock_t *lock ); 2 加鎖,嘗試性加鎖,解鎖。 int pthread_spin_lock( pthread_spinlock_t *lock ); int pthread_spin_trylock( pthread_spinlock_t *lock ); int pthread_spin_unlock( pthread_spinlock_t *lock );
7:屏障。
1 初始化,類析構函數(釋放內存前使用) int pthread_barrier_init( pthread_barrier_t *restrict barrier, const pthread_barrierattr_t *restrict attr, unsigned int count ); int pthread_barrier_destroy( pthread_barrier_t *barrier ); // 1 參數count表示須要多少個線程達到此節點後,才能夠繼續運行。count設置後不會改變。 2 當前線程已完成,等待其餘線程。 int pthread_barrier_wait( pthread_barrier_t *barrier ); // 如未知足count數,則此線程進行休眠。 3 初始化 和 類析構函數。 int pthread_barrierattr_init( pthread_barrierattr_t *attr ); int pthread_barrierattr_destroy( pthread_barrierattr_t *attr ); 4 獲取/設置 進程共享屬性。 int pthread_barrierattr_getpshared( const pthread_barrierattr *restrict attr, int *restrict pshared ); int pthread_barrierattr_setpshared( pthread_barrierattr *attr, int pshared );
3、