目录
1.线程创建
2.线程退出
3.线程回收
4.线程分离
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg)
参数:
pthread_t *thread:传出参数,这个子线程的id的地址
const pthread_attr_t *attr:线程属性一般写为NULL
void *(*start_routine) (void *):此线程需要执行的函数指针,函数返回值需要为void*类型
void *arg:此线程需要执行的函数参数的地址,如果多个参数,则定义一个结构体封装参数
返回值:
创建成功返回0,否则返回错误号
头文件:
#include
注意,当主线程销毁时,子线程也就不存在了,因为一个进程的所有线程共享同一块内存空间
如果想要主线程销毁时,不影响子线程继续执行,需要用到线程退出函数
void pthread_exit(void* retval)
参数:
void* retval:自带数据,一般为当前线程想要返回的数据,不返回设置为NULL
用法:
可以在主线程逻辑的末尾使用,主线程退出后,该虚拟地址空间不会被释放,当子线程执行完毕后,该地址空间会被操作系统回收
头文件:
#include
用于主线程回收子线程内核资源,当主线程执行到这个函数时,会阻塞并等待指定的子线程执行完毕退出后,再去继续执行回收资源,这样就避免了主线程在子线程还没有执行完毕就退出的问题,该函数每次只能回收一个线程
int pthread_join(pthread_t tid, void** retval)
参数:
pthread_t tid:当前需要退出线程的id
void** retval:子线程需要返回给主线程的内容,如果不返回设置NULL,配合pthread_exit来使用
返回值:
回收成功返回0,否则返回错误号
对于retval的一些说法:
子线程返回数据有两种方式:
(1)子线程退出时,把返回数写在pthread_exit的retval参数中,然后主线程从pthread_join的retval中读取,需要定义一个全局变量
struct Test
{
int a;
int b;
};
Test test;
void* work(void* arg)
{
//cout << "child thread " << pthread_self() << endl;
test.a = 1;
test.b = 2;
pthread_exit(&test);
return NULL;
}
int main(int argc, char** argv)
{
pthread_t tid;
int thread1 = pthread_create(&tid, NULL, work, NULL);
//cout << "main thread " << pthread_self() << endl;
void* p;
pthread_join(tid, &p);
Test* pt = (Test*)p;
cout << "a: " << pt->a << " b: " << pt->b << endl;
return 0;
}
结果:
a: 1 b: 2
(2)在主线程的栈空间中定义传出变量,然后通过pthread_create的最后一个参数传入到子线程中,无需定义全局变量,也无需使用pthread_exit函数
struct Test
{
int a;
int b;
};
void* work(void* arg)
{
//cout << "child thread " << pthread_self() << endl;
Test* test = (Test*)arg;
test->a = 1;
test->b = 2;
return NULL;
}
int main(int argc, char** argv)
{
pthread_t tid;
Test test;
int thread1 = pthread_create(&tid, NULL, work, &test);
//cout << "main thread " << pthread_self() << endl;
pthread_join(tid, NULL);
cout << "a: " << test.a << " b: " << test.b << endl;
return 0;
}
结果:
a: 1 b: 2
如果主线程负责回收子线程资源,当主线程执行到pthread_join函数时,会被一直阻塞,导致不能继续处理主线程后续的逻辑
当主线程调用线程分离函数pthread_detach时,子线程就和主线程分离了,主线程不再回收子线程的资源,子线程退出后资源将被其他进程回收
虽然分离了,但是当主线程销毁后,子线程依然也不复存在,所以为了不影响子线程执行,会在pthread_detach使用pthread_exit函数
int pthread_detach(pthread_t tid)
参数:
pthread_t tid:需要被分离线程的id
返回值:
为0分离成功
void* work(void* arg)
{
//cout << "child thread " << pthread_self() << endl;
for (int i = 0; i < 5; ++i)
{
cout << i << endl;
}
return NULL;
}
int main(int argc, char** argv)
{
pthread_t tid;
int thread1 = pthread_create(&tid, NULL, work, NULL);
//cout << "main thread " << pthread_self() << endl;
pthread_detach(tid);
pthread_exit(NULL);
return 0;
}
返回:
0
1
2
3
4
学习网站推荐:
爱编程的大丙 线程 | 爱编程的大丙