既然大家已经搜索到这篇博客,想必对于线程和进程及并行的基础知识已不需我赘述,那么我直接进入正题。
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);
}