课时67+74_线程创建+线程分离属性设置
文章目录
1、创建线程—pthread_creat函数
1.1、函数原型
int pthread_create(
pthread_t* thread, //线程ID,无符号长整形,传出参数
const pthread_attr_t* attr, //线程属性
void* (*start_routine)(void), //线程处理函数
void* arg //线程处理函数的参数
)
1.2、函数参数
(1)thread:传出参数,线程创建成功后,会被置为一个合适的值;
(2)attr:线程属性,常用的是线程分离(线程分离后子线程可以释放自己的pcb),默认父子线程不分离,传NULL
(3)start_toutine:回调函数的函数指针,子线程的处理函数
(4)arg:回调函数的参数
1.3、函数返回值
(1)如果线程创建成功,返回0;创建失败返回错误号;
(2)perror()不能用来打印pthread_create函数的错误信息;
1.4、函数使用及注意事项
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
#include <pthread.h> //线程对应的头文件
//回调函数,子线程要做的任务
void* myfun(void* arg)
{
//打印子线程的ID
printf("child thread id:%ld\n",pthread_self());
return NULL;
}
//主函数
int main()
{
//创建一个子线程
pthread_t pthid;
pthread_create(&pthid,NULL,myfun,NULL);
//打印父线程ID
printf("parent thread id:%ld\n",pthread_self());
//循环打印5个数
for(int i=0;i<5;i++)
{
printf("i:%d\n",i);
}
return 0;
}
执行结果:
root@Ubuntu18:/home/remotefs/001.Linux_sys# g++ pthread_creat.cpp -lpthread
root@Ubuntu18:/home/remotefs/001.Linux_sys# ./a.out
parent thread id:140379444696896
i:0
i:1
i:2
i:3
i:4
为什么没有打印子线程ID呢??因为父进程运行完,先结束,父线程地址空间释放,子线程共用父线程的地址空间,子线程被强制退出。
让父线程sleep(2)再return。
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
#include <pthread.h> //线程对应的头文件
//回调函数,子线程要做的任务
void* myfun(void* arg)
{
//打印子线程的ID
printf("child thread id:%ld\n",pthread_self());
return NULL;
}
//主函数
int main()
{
//创建一个子线程
pthread_t pthid;
pthread_create(&pthid,NULL,myfun,NULL);
//打印父线程ID
printf("parent thread id:%ld\n",pthread_self());
//循环打印5个数
for(int i=0;i<5;i++)
{
printf("i:%d\n",i);
}
//让父线程sleep两秒,保证子线程先结束,父线程后结束
sleep(2);
return 0;
}
运行结果:
root@Ubuntu18:/home/remotefs/001.Linux_sys# ./a.out
child thread id:140618172331776
parent thread id:140618180847424
i:0
i:1
i:2
i:3
i:4
1.5、通过线程属性设置线程分离
通过设置pthread_create
函数的第二个参数const pthread_attr_t* attr, //线程属性
设置线程分离。
设置线程分离后:
(1)子线程会回收自己的pcb(进程控制块);
(2)不需要再调用pthread_join函数回收子线程pcb;
(3)不用再通过调用pthread_detach(pthread_t thread)
函数对已经创建好的子线程设置线程分离;
第一步:定义线程属性变量
pthread_attr_t attr;
第二步:
对线程属性变量初始化,调用初始化函数
int pthread_attr_init(pthread_attr_t* attr)
第三步:设置线程分离属性,调用设置线程属性的函数
int pthread_attr_setdetachstate(pthread_attr_t* attr,int detachstate)
其中:
pthread_attr_t* attr;
//线程实行
int detachstate;
//要设置的线程属性
detachstate对应的宏定义有两个:
PTHREAD_CREATE_DETACHED
(分离)
PTHREAD_CREATE_JOINABLE
(非分离)
第四步:
释放线程分离属性资源
int pthread_attr_destroy(pthread_attr_t* attr)
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
#include <pthread.h> //线程对应的头文件
//回调函数,子线程要做的任务
void* myfun(void* arg)
{
//打印子线程的ID
printf("child thread id:%ld\n",pthread_self());
return NULL;
}
//主函数
int main()
{
//创建一个子线程
pthread_t pthid;
//初始化线程属性
pthread_attr_t attr;
pthread_attr_init(&attr);
//设置线程属性为分离
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
//创建线程时设置线程分离,子线程可以自己释放自己pcb
pthread_create(&pthid,&attr,myfun,NULL);
//打印父线程ID
printf("parent thread id:%ld\n",pthread_self());
//循环打印5个数
for(int i=0;i<5;i++)
{
printf("i:%d\n",i);
}
//让父线程sleep两秒,保证子线程先结束,父线程后结束
sleep(2);
//释放线程属性的资源
pthread_attr_destroy(&attr);
return 0;
}