線程api && 線程資料類型 && 避免死結 &&鏈鎖,
避免死結:
1,固定加鎖層次
如果需要同時加鎖A,B,那麼固定加鎖順序,比如只能先加鎖A,後加鎖B;
2,試加鎖和回退
如果加鎖集合中第一個互斥量,那麼對其他互斥量加鎖時,使用pthread_mutex_trylock如果失敗,釋放所有已經加的鎖
鏈鎖:
兩個鎖的範圍疊加,當代碼鎖住一個互斥量進入地區時,還需要第二個互斥量;
鏈鎖應該用在多個線程同時活躍在層次的不同部分時
TYPE
pthread_t 線程標識符
pthread_mutex_t 互斥量
pthraed_code_t 條件變數
pthread_ket_t 線程私人權握訪問鍵
pthread_attr_t 線程屬性對象
pthread_mutexattr_t 互斥量屬性對象
pthread_condattr_t 條件變數屬性對象
pthread_once_t 一次性初始化 控制變數
API
int pthread_equal(pthread_t t1, pthread_t t2);
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void* (*start) (void*), void *arg)
pthread_t pthread_self(void);
int sched_yield(void);
int pthread_exit(void*value_ptr);//終止線程的執行,如果main線程調用,那麼子線程會執行完,但是如果main線程調用return,子線程會直接結束,參數為返回的字串
int pthread_detach(pthread_t thread); //分離一個正在啟動並執行線程不對線程帶來任何影響,僅僅是通知系統當該線程結束時,其所屬資源會被回收.
一個沒被分離的線程終止時,會保留虛擬記憶體,包括他們的堆棧,還有其他系統資源.線程自身detach之後,其他線程在使用pthread_join就會報錯,因為線程資源以及釋放
int pthread_join(pthread_t thread, void **val); //等待線程結束,釋放thread線程資源
pthread_join 和pthread_detach 看誰先後執行,決定pthread_join釋放能擷取到狀態,
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER 靜態初始化預設屬性的互斥量
int pthread_mutex_init(pthread_mutex_t *mutex,pthread_mutex_attr_t *attr);動態初始化互斥量
int pthread_mutex_destory(pthread_mutex_t *mutex); 在釋放動態初始化的互斥量之後,在釋放空間,也就destory,然後free
檔案=鎖
flockfile()
ftrylockfile()
funlockfile()
擷取使用者和終端ID
getlogin_r
ctermid()
ttyname_r()
搜獲目錄
readdir_r
字串
strtok_r
時間表示
char *asctime_r(), ctime_r () , gmtime_r(), localtime_t(),read_r
組資料庫:getgrgid_r, getgrnam_r,
使用者資料庫:getpwuid_r,getpwnam_r
擷取系統變數的值sysconf
訊號
當線程和訊號相遇時,只要有可能盡量在主線程使用pthread_sigmask來屏蔽訊號,然後同步的在專用線程
中使用sigwait,如果必須線上程內使用sigaction(或等價)的處理同步訊號(如SIGSEGV),要特別小心,
訊號處理函數內應盡量少做工作
與硬體相關的同步訊號包括SIGSEGV,SIGFPE,SIGTRAP,他們被送到引起該硬體情況的線程,肯定不會送到其他線程
線程訊號掩碼函數 :pthread_sigmask(),一個線程建立時,他繼承了建立該線程的訊號掩碼。
pthread_kill()向指定的線程發送訊號,僅限本進程內,如果發送SIGKILL訊號,訊號不止會殺死指定線程,還會殺死所有線程(包括主線程)
SIGSTOP和SIGKILL訊號是不可捕獲的
SIGTSTP與SIGSTOP都是使進程暫停(都使用SIGCONT讓進程重新啟用)。唯一的區別是SIGSTOP不可以捕獲。
捕捉SIGTSTP後一般處理如下:
1)處理完額外的事
2)恢複預設處理
3)發送SIGTSTP訊號給自己。(使進程進入suspend狀態。)
int raise(int sig); 給當前線程或進程發訊號
對訊號集的處理
int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigaddset(sigset_t *set, int signum);
int sigdelset(sigset_t *set, int signum);
int sigismember(const sigset_t *set, int signum);