既然大家已經搜索到這篇博客,想必對於線程和進程及並行的基礎知識已不需我贅述,那麼我直接進入正題。
pthread的所有API均定義在ANSI/IEEE POSIX 1003.1 - 1995 standard。API可以粗略的分爲四大類:線程管理、互斥、條件變量、同步。所有的API均以pthread_爲前綴。
所以線程庫的使用都需要從創建和結束線程開始,pthread也不例外:
pthread_create(pthread_t*thread,pthread_attr_t*attr,funcptr*start_routine,void*arg,);是創建線程的API,需要注意的是,thread內存並不是由此API內部分配,而是需要我們預先定義並引用;attr線程屬性我們暫且不管,如果使用的話需要線程初始化前pthread_attr_init(attr),線程創建完成後pthread_attr_destroy(attr),在下面的例子中我們可以看到目前來講是否有attr不影響結果;
線程的結束方式:(1)當線程函數正常返回時,線程自動結束(2)線程在自身內部調用pthread_exit()將會立即終止自身(3)其他線程通過調用pthread_cancel(pthread_t thread)來結束其他線程(4)整個進程結束。
相對於其他線程庫的terminate API,pthread_exit要“柔和”的多。(1)當main()結束時,而其他線程還在運行並且沒有強行調用pthread_exit,行爲是確定的!這些線程全會自動結束。(2)但是我們建議你將pthread_exit(status)作爲main()的最後一行,因爲它將保證你把線程執行完(status代表返回時線程狀態)。
#define HAVE_STRUCT_TIMESPEC 1
#include<pthread.h>
#include<iostream>
using namespace std;
struct userdata
{
int thread_index;
int data;
};
void *thread_func(void *data)
{
userdata * localdata = (userdata *)data;
for (int i = 0; i < 100; i++)
{
cout << "thread" << localdata->thread_index << ":" << localdata->data << endl;
localdata->data++;
}
//we always have pthread_exit in the end of thread
pthread_exit(NULL);
return NULL;
}
int main(void)
{
//first,we should allocate the pthread_t ourseleves;
pthread_t rd1_thread ;
pthread_t rd2_thread;
//declare and allocate attr;
pthread_attr_t *attr = nullptr; pthread_attr_init(attr);
//define userdata
userdata rd1_data,rd2_data;
rd1_data.data = 0; rd1_data.thread_index = 1;
rd2_data.data = 0; rd2_data.thread_index = 2;
//create thread
if (int rc=pthread_create(&rd1_thread, attr, thread_func, &rd1_data))
{
cout << "create thread erro:" << rc << endl;
}
if (int rc = pthread_create(&rd2_thread, NULL, thread_func, &rd2_data))
{
cout << "create thread erro:" << rc << endl;
}
_sleep(1000);
//some clean
pthread_attr_destroy(attr);
pthread_exit(NULL);
}