參考1 https://computing.llnl.gov/tutorials/pthreads/
參考2 http://man7.org/linux/man-pages/man7/pthreads.7.htmlhtml
int pthread_join(pthread_t, void**);
阻塞調用線程,直至指定pthread_t線程終止pthread_attr_t data
typepthread_attr_init()
pthread_attr_setdetachstate()
pthread_attr_destroy()
pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); for(t=0; t<NUM_THREADS; t++) { printf("Main: creating thread %ld\n", t); rc = pthread_create(&thread[t], &attr, BusyWork, (void *)t); //一個attr能夠給多個線程使用 if (rc) { printf("ERROR; return code from pthread_create() is %d\n", rc); exit(-1); } } pthread_attr_destroy(&attr); //記得釋放資源。create執行完以後就能夠釋放,而不用等待線程結束
pthread_detach()
來設置線程爲不可join,即便它被建立的時候被設置爲joinable。這個動做不可逆pthread_attr_setstacksize
能夠用來設置須要的stack大小pthread_attr_getstackaddr
和pthread_attr_setstackaddr
能夠用來設置stack須要放置到特定的內存區域size_t stacksize; pthread_attr_init(&attr); pthread_attr_getstacksize (&attr, &stacksize); printf("Default stack size = %li\n", stacksize); size = 10000; //設置爲10000bytes pthread_attr_setstacksize (&attr, stacksize); printf("set stack size = %li\n", stacksize); pthread_create(&threads[t], &attr, dowork, (void *)t);
//destroy,成功則返回0 int pthread_mutex_destroy(pthread_mutex_t *mutex); //動態初始化,成功則返回0. 若是attr爲NULL,那麼將使用默認屬性,至關於PTHREAD_MUTEX_INITIALIZER int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr); //使用默認參數靜態初始化 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; //mutex屬性 int pthread_mutexattr_destroy(pthread_mutexattr_t *attr); int pthread_mutexattr_init(pthread_mutexattr_t *attr);
pthread_mutex_init
從新初始化不能夠重複初始化已經初始化了的mutexlinux
//若是別的線程已經lock,那會一直阻塞當前線程直至得到鎖 int pthread_mutex_lock(pthread_mutex_t *mutex); int pthread_mutex_trylock(pthread_mutex_t *mutex); int pthread_mutex_unlock(pthread_mutex_t *mutex);
mutex類型 | 性質 |
---|---|
PTHREAD_MUTEX_NORMAL | 對mutex的重複lock,即本線程已經lock了mutex,在沒有unlock以前又嘗試lock,將致使死鎖行爲;unlock一個沒有被本線程lock或者沒有被任何線程lock的mutex,將致使未定義行爲 |
PTHREAD_MUTEX_ERRORCHECK | 嘗試重複lock一個mutex將不會死鎖,而是返回一個錯誤值;unlock一個沒有被本線程lock或者沒有被任何線程lock的mutex,也會返回錯誤值 |
PTHREAD_MUTEX_RECURSIVE | mutex能夠被重複lock。每次lock會增長相關計數,直至經過unlock使計數達到0時,才能夠被別的線程lock;unlock一個沒有被本線程lock或者沒有被任何線程lock的mutex,也會返回錯誤值 |
PTHREAD_MUTEX_DEFAULT | 重複lock會致使未定義行爲(NORMAL中會致使死鎖);unlock一個沒有被本線程lock或者沒有被任何線程lock的mutex,也將致使未定義行爲。 不過,在NDK的定義中,直接把PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL |
pthread_mutex_trylock
與pthread_mutex_lock
只有一點區別:若是當前mutex被任意線程lock,pthread_mutex_trylock
都將會馬上返回。若是mutex是PTHREAD_MUTEX_RECURSIVE的,且mutex已經被當前調用線程lock,pthread_mutex_trylock
也一樣會致使計數增一,並返回success。condition variable 常常和mutex一塊兒使用dom
int pthread_cond_destroy(pthread_cond_t *cond); int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr); pthread_cond_t cond = PTHREAD_COND_INITIALIZER; int pthread_condattr_destroy(pthread_condattr_t *attr); int pthread_condattr_init(pthread_condattr_t *attr);
pthread_cond_wait(), pthread_cond_timedwait(), pthread_cond_signal(), pthread_cond_broadcast(), pthread_cond_destroy()
都會產生未定義行爲通常使用流程:
函數
int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict abstime); int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
pthread_cond_broadcast()
或pthread_cond_signal()
的調用都會產生調用wait的線程已經blocked on the condition variable的效果。pthread_cond_timedwait
因爲超時返回以後,條件也可能已經知足。總之。任什麼時候候wait返回,都須要從新評估條件是否知足,這點很是重要pthread_cond_timedwait()
和pthread_cond_wait()
是equivalent的,除了:當signaled或者broadcasted超過指定時間,pthread_cond_timedwait()
就會返回返回error。同時,cv還能夠支持 Clock Selection,選擇不一樣的Clock來measure指定的時間int pthread_cond_broadcast(pthread_cond_t *cond); int pthread_cond_signal(pthread_cond_t *cond);
pthread_cond_broadcast()
有:ui
pthread_kill
參考https://www.cnblogs.com/biyeymyhjob/archive/2012/10/11/2720377.html
---線程
pthread_t pthread_self(void);
返回調用線程的thread idrest
int pthread_equal(pthread_t t1, pthread_t t2);
比較兩個ID是否相等,若是相等則返回not-zero value,不相等則返回0。因爲pthread_t結果opaque,因此不該該用==
來比較code
int pthread_once(pthread_once_t *once_control, void (*init_routine)(void));
:在進程中,任何首次調用這個函數的線程,在pthread_once_t once_control = PTHREAD_ONCE_INIT
的時候,會調用init_routine
程序。而且當此函數返回的時候,init_routine
已經執行完了(這裏沒有說init_routine
會阻塞調用線程,可能考慮的是,當線程A已經調用init_routine
,而另一個線程B也調用了pthread_once
,那麼是否B也會等待A調用的init_routine
執行完畢?)。若是成功完成,則pthread_once
返回0。若是once_control
參數不是PTHREAD_ONCE_INIT
,那麼行爲將是undefined。在LinuxThreads中:htm
在LinuxThreads中,實際"一次性函數"的執行狀態有三種:NEVER(0)、IN_PROGRESS(1)、DONE (2),若是once初值設爲1,則因爲全部pthread_once()都必須等待其中一個激發"已執行一次"信號,所以全部pthread_once ()都會陷入永久的等待中;若是設爲2,則表示該函數已執行過一次,從而全部pthread_once()都會當即返回0。blog
這個函數在當沒法編輯進程的main函數,好比寫一個庫的時候,就頗有用。
TODO:若是多個線程使用的init_routine
不相同怎麼辦?或者好比本身開發庫,可是user的main中已經使用不一樣的init_routine
調用了pthread_once
,那麼會是什麼結果?