linux學習筆記之線程同步機制

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、

相關文章
相關標籤/搜索