说明
如题,这个属性是在使用pthread_create这个函数时设置的,第二个参数就是设置分离属性的。
什么是分离属性?
首先分离属性是线程的一个属性,有了分离属性的线程,不需要别的线程去接合自己了(使用pthread_join回收资源)。
设置了分离属性的线程 ->不需要pthread_join()
设置了非分离属性的线程 ->需要pthread_join(),如果在线程创建时,没有设置分离属性时,默认创建的线程就是非分离线程。
如何创建分离属性线程?
方法一
添加一个分离属性到一个属性变量中,然后使用属性变量去创建一个线程,那么创建出来的线程就是具有分离属性的线程。
1)定义一个分离属性
pthread_attr_t attr;
2)初始化属性变量
#include <pthread.h>
int pthread_attr_init(pthread_attr_t *attr);
参数传入的是这个属性变量的地址
参数:
attr:未初始化的属性变量
返回值:
成功:0
失败:非0错误码
3)设置分离属性到属性变量中。
#include <pthread.h>
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
参数:
attr:已经初始化过的属性变量
detachstate:
PTHREAD_CREATE_DETACHED -> 分离属性
PTHREAD_CREATE_JOINABLE -> 非分离属性 等同于 pthread_create(&thread_id, NULL, start_pthread, &val);
返回值:
成功:0
失败:非0错误码
4)使用属性变量去创建一个新的线程。
pthread_create(&tid,&attr,.....); -> 创建出来的线程就是分离属性的线程,不需要pthread_join()
5)销毁属性变量。
int pthread_attr_destroy(pthread_attr_t *attr);
参数:
attr:已经初始化过的属性变量
返回值:
成功:0
失败:非0错误码
检验一下:
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
//全局变量
int g_retval = 100;
//子线程
void *start_pthread(void *arg)
{
printf("cnt:%d\n", *((unsigned int *)arg));
}
int main(void)
{
unsigned int cnt = 0;
void *retval_p = NULL;
pthread_t thread_id;
//线程属性变量
pthread_attr_t attr;
//初始化属性变量
pthread_attr_init(&attr);
//设置分享属性
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
//主线程 运行时间比子线程时间长,主线程运行退出后,回收子线程资源
while (1)
{
cnt++;
//线程创建
int ret = pthread_create(&thread_id, &attr, start_pthread, &cnt);
if(ret != 0)
{
printf("pthread_create fail\n");
return -1;
}
}
return 0;
}
运行结果:
在这个图可以看到,他创建了很多个线程。并且是我按下ctrl+c后才终止的,那就说明了,设置了分离属性的线程,在线程结束后,会自动清理资源。(非分离属性下只会打印3w左右)。
方法二
先创建一个普通线程(分享属性设置为NULL, 默认的分享属性为不分离),然后在线程中调用一个设置分离属性的函数,那么这个线程就变成分离的属性。
1)设置线程本身的属性为分离属性。
#include <pthread.h>
int pthread_detach(pthread_t thread);
函数作用:
设置分离属性给线程
参数:
thread:需要设置分离属性的线程的ID号
返回值:
成功:0
失败:非0错误码
2)获取线程的ID号。
#include <pthread.h>
pthread_t pthread_self(void);
参数:
无
返回值:线程的ID号。
检验一下:
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
//全局变量
int g_retval = 100;
//子线程
void *start_pthread(void *arg)
{
pthread_t thread_id;
//获取线程ID
thread_id = pthread_self();
//设置为分离属性
pthread_detach(thread_id);
printf("cnt:%d\n", *((unsigned int *)arg));
}
int main(void)
{
unsigned int cnt = 0;
void *retval_p = NULL;
pthread_t thread_id;
while (1)
{
cnt++;
//线程创建
int ret = pthread_create(&thread_id, NULL, start_pthread, &cnt);
if(ret != 0)
{
printf("pthread_create fail\n");
return -1;
}
}
return 0;
}
可以看到它也可以无限创建线程。