第十二章 線程控制

線程限制

線程屬性

#include <pthread.h>
int pthread_attr_init(pthread_attr_t *attr);
in pthread_attr_destory(pthread_attr_t *attr);
//分離狀態(tài)
int pthread_attr_getdetachstate(const pthread_attr_t *restrict attr,int *detachstate);
int pthread_attr_setdetachstate(pthread_attr_t *attr, int *detachstate);
//棧的最低地址
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);
//棧的大小
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);
//線程棧末尾之后用以避免棧溢出的擴展內(nèi)存的大小
iint pthread_attr_getguardsize(const pthread_attr_t *restrict attr,size_t *restrict guardsize);
int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);

http://www.cnblogs.com/mydomain/archive/2011/08/14/2138454.htm

線程的分離狀態(tài)決定一個線程以什么樣的方式來終止自己。在上面的例子中,我們采用了線程的默認屬性,即為非分離狀態(tài)(即可結合的,joinable,需要回收),這種情況下,原有的線程等待創(chuàng)建的線程結束;只有當pthread_join()函數(shù)返回時,創(chuàng)建的線程才算終止,才能釋放自己占用的系統(tǒng)資源。而分離線程不是這樣子的,它沒有被其他的線程所等待,自己運行結束了,線程也就終止了,馬上釋放系統(tǒng)資源。程序員應該根據(jù)自己的需要,選擇適當?shù)姆蛛x狀態(tài)。

同步屬性

互斥量

#include <pthread.h>
int pthread_mutexattr_init(pthread_mutexattr_t *attr);
int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);

//進程共享屬性
int pthread_mutexattr_getpshared(const pthread_mutexattr_t *restrict attr,int *restrict pshared);
int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr,int pshared);
//健壯的互斥量屬性
int pthread_mutexattr_getrobust(const pthread_mutexattr_t *restrict attr,int *restrict robust);
int pthread_mutexattr_setrobust(pthread_mutexattr_t *attr,int robust);
//指明與該互斥量相關的 狀態(tài)在互斥量解鎖之前是一致                             
int pthread_mutex_consistent(pthread_mutex_t *mutex);
 //互斥量類型屬性                                
int pthread_mutexattr_gettype(const pthread_mutexattr_t *restrict attr, int *restrict type);
int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type);

讀寫鎖

#include <pthread.h>
int pthread_rwlockattr_init(pthread_rwlockattr_t *attr);
int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr);
//進程共享屬性
int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *restrict attr,int *restrict pshared);
int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr,int pshared);

條件變量

#include <pthread.h>
int pthread_condattr_init(pthread_condattr_t *attr);
int pthread_condattr_destroy(pthread_condattr_t *attr);
//進程共享屬性
int pthread_condattr_getpshared(const pthread_condattr_t *restrict attr,int *restrict pshared);
int pthread_condattr_setpshared(pthread_condattr_t *attr,int pshared);
//時鐘屬性
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);

屏障

#include <pthread.h>
int pthread_barrierattr_init(pthread_barrierattr_t *attr);
int pthread_barrierattr_destroy(pthread_barrierattr_t *attr);
//進程共享屬性
int pthread_barrierattr_getpshared(const pthread_barrierattr_t *restrict attr,int *restrict pshared);
int pthread_barrierattr_setpshared(pthread_barrierattr_t *attr,int pshared);

重入

#include <stdio.h>
int ftrylockfile(FILE *fp);
void flockfile(FILE *fp);
void funlockfile(FILE *fp);

線程特定數(shù)據(jù)

#include <pthread.h>
int pthread_key_create(pthread_key_t *keyp,void(*destruct)(void *));
int pthread_key_delete(pthread_key_t keyp);

pthread_once_t initflag = PTHREAD_ONCE_INIT;
int pthread_once(pthread_once_t *initflag, void (*initfn)(void));

void destructor(void *);
pthread_key_t key;
pthread_once_t init_done = PTHREAD_ONCE_INIT;
void thread_init(void)
{
    err = pthread_key_create(&key, destructor);
}
int threadfunc(void *arg)
{
    pthread_once(&init_done, thread_init);
}

void *pthread_getspecific(pthread_key_t key);
int pthread_setspecific(pthread_key_t key,const void *value)

取消選項

#include <pthread.h>
int pthread_setcancelstate(int state, int *oldstate);
void pthread_testcancel(void);
int pthread_setcanceltype(int type, int *oldtype);

線程和信號

#include <signal.h>
int pthread_sigmask(int how,const sigset_t *restrict set,sigset_t *restrict oset);
int sigwait(const sigset_t *restrict set, int *restrict signop);
int pthread_kill(pthread_t thread,int signo);

線程可以通過調(diào)用 sigwait 等待一個或多個信號的出現(xiàn)

線程和fork

子進程通過繼承整個地址空間的副本,還從父進程那兒繼承了每個互斥量、讀寫鎖和條件變 量的狀態(tài)

如果父進程包含一個以上的線程,子進程在 fork 返回以后,如果緊接著不是馬上調(diào) 用 exec 的話,就需要清理鎖狀態(tài)

POSIX.1 聲明,在 fork 返回和子進程調(diào) 用其中一個 exec 函數(shù)之間,子進程只能調(diào)用異步信號安全的函數(shù),這就限制了在調(diào)用 exec 之 前子進程能做什么,但不涉及子進程中鎖狀態(tài)的問題

要清除鎖狀態(tài),可以通過調(diào)用 pthread_atfork 函數(shù)建立 fork 處理程序

#include <pthread.h>
int pthread_atfork(void (*prepare)(void),void (*parent)(void),void (*child)(void));
  1. prepare fork 處理程序由父進程 在 fork 創(chuàng)建子進程前調(diào)用。這個 fork 處理程序的任務是獲取父進程定義的所有鎖
  2. parent fork 處理 程序是在 fork 創(chuàng)建子進程以后、返回之前在父進程上下文中調(diào)用的。這個 fork 處理程序的任務是對 prepare fork 處理程序獲取的所有鎖進行解鎖
  3. child fork 處理程序在 fork 返回之前在子進程上下文中調(diào)用。與 parent fork 處理程序一樣,child fork 處理程序也必須釋放 prepare fork 處理程序獲取的所有鎖。

線程和IO

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容