C++?pthread入門(mén)指南
一、pthread簡(jiǎn)介
pthread是C++98接口且只支持Linux,使用時(shí)需要包含頭文件#include <pthread.h>,編譯時(shí)需要鏈接pthread庫(kù),其中p是POSIX的縮寫(xiě),而POSIX是Portable Operating System Interface的縮寫(xiě),是IEEE為要在各種UNIX操作系統(tǒng)上運(yùn)行軟件,而定義API的一系列互相關(guān)聯(lián)的標(biāo)準(zhǔn)的總稱。(Windows環(huán)境下無(wú)pthread,Linux GCC4.6以下編譯需加-pthread編譯選項(xiàng))
1、線程創(chuàng)建
int pthread_create (pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *),void *arg);
若創(chuàng)建成功,返回0;若出錯(cuò),則返回錯(cuò)誤編號(hào)。
- thread 是線程標(biāo)識(shí)符,但這個(gè)參數(shù)不是由用戶指定的,而是由 pthread_create 函數(shù)在創(chuàng)建時(shí)將新的線程的標(biāo)識(shí)符放到這個(gè)變量中。
- attr 指定線程的屬性,包含了線程的調(diào)度策略,堆棧的相關(guān)信息,join or detach 的狀態(tài)等,可以用 NULL 表示默認(rèn)屬性。
- start_routine 指定線程開(kāi)始運(yùn)行的函數(shù)。
- arg 是 start_routine 所需要的參數(shù),是一個(gè)無(wú)類型指針。
pthread_attr_t 操作函數(shù):
pthread_attr_t attr; // 聲明attr pthread_attr_init(&attr); // 創(chuàng)建attr pthread_attr_destroy(&attr); // 銷毀attr pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); // 設(shè)置為joinable
2、線程終止
void pthread_exit (void *retval); int pthread_cancel (pthread_t thread);
當(dāng)發(fā)生以下情形之一時(shí),線程就會(huì)結(jié)束:
- 線程運(yùn)行的函數(shù)return了,也就是線程的任務(wù)已經(jīng)完成;
- 線程調(diào)用了 pthread_exit 函數(shù);
- 其他線程調(diào)用 pthread_cancel 結(jié)束這個(gè)線程;
- 進(jìn)程調(diào)用 exec() 或 exit(),結(jié)束了;
- main() 函數(shù)先結(jié)束了,而且 main() 自己沒(méi)有調(diào)用 pthread_exit 來(lái)等所有線程完成任務(wù)。
當(dāng)然,一個(gè)線程結(jié)束,并不意味著它的所有信息都已經(jīng)消失,后面會(huì)看到僵尸線程的問(wèn)題。
一個(gè)線程可以通過(guò)調(diào)用 pthread_cancel 函數(shù)來(lái)請(qǐng)求取消同一進(jìn)程中的線程,這個(gè)線程由thread 參數(shù)指定。如果操作成功則返回0,失敗則返回對(duì)應(yīng)的錯(cuò)誤編號(hào)。
3、線程同步
int pthread_join(pthread_t threadid, void **value_ptr); int pthread_detach (threadid);
阻塞是線程之間同步的一種方法。pthread_join 函數(shù)會(huì)讓調(diào)用它的線程等待 threadid 線程運(yùn)行結(jié)束之后再運(yùn)行,value_ptr 存放了其他線程的返回值。
一個(gè)可以被join的線程,僅僅可以被別的一個(gè)線程 join,如果同時(shí)有多個(gè)線程嘗試 join 同一個(gè)線程時(shí),最終結(jié)果是未知的。另外,線程不能 join 自己。
值得注意的的是:僵尸線程 ( “zombie” thread )是一種已經(jīng)退出了的 joinable 的線程,但是等待其他線程調(diào)用
pthread_join 來(lái) join 它,以收集它的退出信息(exit status)。如果沒(méi)有其他線程調(diào)用 pthread_join 來(lái)
join 它的話,它占用的一些系統(tǒng)資源不會(huì)被釋放,比如堆棧。如果main()函數(shù)需要長(zhǎng)時(shí)間運(yùn)行,并且創(chuàng)建大量 joinable的線程,就有可能出現(xiàn)堆棧不足的 error 。 對(duì)于那些不需要 join 的線程,最好利用
pthread_detach,這樣它運(yùn)行結(jié)束后,資源就會(huì)及時(shí)得到釋放。注意一個(gè)線程被使用 pthread_detach
之后,它就不能再被改成 joinable 的了。 總而言之,創(chuàng)建的每一個(gè)線程都應(yīng)該使用 pthread_join 或者
pthread_detach 其中一個(gè),以防止僵尸線程的出現(xiàn)。
4、其他函數(shù)
pthread_self (); // 返回當(dāng)前線程的 thread ID pthread_equal (thread1,thread2); // pthread_equal 比較兩個(gè)線程的 ID,如果不同則返回0,否則返回一個(gè)非零值 // 互斥鎖 pthread_mutex_t mutexsum; pthread_mutex_init (mutex,attr); pthread_mutex_destroy (pthread_mutex_t *mutex); pthread_mutexattr_init (attr); pthread_mutexattr_destroy (attr); phtread_mutex_lock(pthread_mutex_t *mutex); phtread_mutex_trylock(pthread_mutex_t *mutex); phtread_mutex_unlock(pthread_mutex_t *mutex);
5、示例代碼
#include<stdlib.h> #include <pthread.h> #include <stdio.h> #include <math.h> #define NUM_THREADS 4 void *BusyWork(void *t) { int i; long tid; double result = 0.0; tid = (long) t; printf("Thread %ld starting...\n", tid); for (i = 0; i < 1000000; i++) { result = result + sin(i) * tan(i); } printf("Thread %ld done. Result = %e\n", tid, result); pthread_exit((void *) t); } int main(int argc, char *argv[]) { pthread_t thread[NUM_THREADS]; pthread_attr_t attr; int rc; long t; void *status; /* Initialize and set thread detached attribute */ 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); if (rc) { printf("ERROR; return code from pthread_create() is %d\n", rc); exit(-1); } } /* Free attribute and wait for the other threads */ pthread_attr_destroy(&attr); for (t = 0; t < NUM_THREADS; t++) { rc = pthread_join(thread[t], &status); if (rc) { printf("ERROR; return code from pthread_join() is %d\n", rc); exit(-1); } printf("Main: completed join with thread %ld having a status of %ld\n", t, (long) status); } printf("Main: program completed. Exiting.\n"); pthread_exit(NULL); }
Main: creating thread 0 Main: creating thread 1 Thread 0 starting... Thread 1 starting... Main: creating thread 2 Main: creating thread 3 Thread 2 starting... Thread 3 starting... Thread 1 done. Result = -3.153838e+06 Thread 0 done. Result = -3.153838e+06 Main: completed join with thread 0 having a status of 0 Main: completed join with thread 1 having a status of 1 Thread 3 done. Result = -3.153838e+06 Thread 2 done. Result = -3.153838e+06 Main: completed join with thread 2 having a status of 2 Main: completed join with thread 3 having a status of 3 Main: program completed. Exiting.
參考鏈接:C++ 多線程編程(二):pthread的基本使用
到此這篇關(guān)于C++ pthread入門(mén)指南的文章就介紹到這了,更多相關(guān)C++ pthread內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
c++中處理相關(guān)數(shù)學(xué)函數(shù)
數(shù)學(xué)庫(kù)函數(shù)聲明在 math.h 中,主要有:2013-04-04VSCode同時(shí)更改所有相同的變量名或類名的圖文教程
這篇文章主要介紹了VSCode同時(shí)更改所有相同的變量名或類名,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-05-05Visual Studio Code 配置C、C++環(huán)境/編譯并運(yùn)行的流程分析
這篇文章主要介紹了Visual Studio Code 配置C、C++環(huán)境/編譯并運(yùn)行的流程分析,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-05-05c字符串,string對(duì)象,字符串字面值的區(qū)別詳解
以下是對(duì)c字符串,string對(duì)象,字符串字面值的區(qū)別進(jìn)行了詳細(xì)的介紹,需要朋友可以 過(guò)來(lái)參考下2013-09-09vs2019安裝及簡(jiǎn)單處理技巧(超詳細(xì))
這篇文章主要介紹了vs2019安裝及簡(jiǎn)單處理方法,本文是一篇非常詳細(xì)的教程,通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06VC實(shí)現(xiàn)動(dòng)態(tài)菜單的創(chuàng)建方法
這篇文章主要介紹了VC實(shí)現(xiàn)動(dòng)態(tài)菜單的創(chuàng)建方法,需要的朋友可以參考下2014-07-07