当前位置: 首页 > news >正文

linux下线程分离属性

linux下线程分离属性

  • 一、线程的属性---分离属性
  • 二、线程属性设置
    • 2.1 线程创建前设置分离属性
    • 2.2 线程创建后设置分离属性

一、线程的属性—分离属性

什么是分离属性?
首先分离属性是线程的一个属性,有了分离属性的线程,不需要别的线程去接合自己的(回收自己的资源)。
a.线程的分离属性有两种:分离态(detached)和非分离态(joinable)。

b.非分离态的线程只有在调用pthread_join之后才会完全释放自己所占用的资源,可以用pthread_detach函数将线程修改为分离态,分离态的线程在线程结束后由系统自动释放其所占用的所有资源;
c.线程创建后默认属性是非分离态,需要调用pthread_join释放线程所占用的资源;

但是虽然说是分离的,但是进程退出了,该线程还是会退出的。
总结:
设置了分离属性的线程 -> 不需要pthread_join()
设置了非分离属性的线程 -> 需要pthread_join() -> 默认创建的普通属性线程就是非分离线程。
退出进程,所有子线程都会消亡,系统会回收他们资源。

如果设置为非分离属性的线程,且不去回收子线程资源,那么一个进程创建的子线程数据是有限,请下面程序(环境ubuntu20.04 64位)

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>//定义退出的值为全局变量
int retval = 10;//子线程
void *start_pthread(void *arg)
{int cnt = 0;printf("arg:%ld\n", *((unsigned long *)arg));}int main(void)
{int cnt = 0;unsigned long val = 0;pthread_t  thread_id;//主线程 运行时间比子线程时间长,主线程运行退出后,回收子线程资源while (1){//线程创建 非分离int ret = pthread_create(&thread_id, NULL, start_pthread, &val);if(ret != 0){printf("pthread_create fail\n");return -1;}    val++;}printf("接合子线程成功\n");return 0;}

运行效果
在这里插入图片描述

如果不设置为分离属性(主不回收子线程资源),创建到32749条时,创建线程失败

二、线程属性设置

线程属性设置通常有两个种,一种是在创建前设置好分离属性,别一个种是线程运行后,再设置线程属性接下来先看第一种情况。

2.1 线程创建前设置分离属性

线程创建前设置分离属性就是添加一个分离属性到一个属性变量中,然后使用属性变量去创建一个线程,那么创建出来的线程就是具有分离属性的线程。
接下来看函数

1)定义一个属性变量 -> 数据类型:pthread_attr_t

pthread_attr_t attr;

2)初始化属性变量。 -> pthread_attr_init() -> man 3 pthread_attr_init

#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)销毁属性变量。 -> pthread_attr_destroy() -> man 3 pthread_attr_destroy

int pthread_attr_destroy(pthread_attr_t *attr);

参数:
attr:已经初始化过的属性变量
返回值:
成功:0
失败:非0错误码

案例代码

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>//定义退出的值为全局变量
int retval = 10;//子线程有分离--不需要接合
void *start_pthread(void *arg)
{int cnt = 0;printf("arg:%ld\n", *((unsigned long *)arg));}int main(void)
{int cnt = 0;unsigned long val = 0;pthread_t  thread_id;//定义分享属性变量 pthread_attr_t attr;//初始化属性变量pthread_attr_init(&attr);//设置线程属性--分离属性pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);//主线程 运行时间比子线程时间长,主线程运行退出后,回收子线程资源while (1){//线程创建 分离属性int ret = pthread_create(&thread_id, &attr, start_pthread, &val);if(ret != 0){printf("pthread_create fail\n");return -1;}    val++;}printf("接合子线程成功\n");return 0;}

在这里插入图片描述
分离属性后的线程,可以自动消亡,主线程可以无限创建子线程。

2.2 线程创建后设置分离属性

先创建一个普通线程(分享属性设置为NULL, 默认的分享属性为不分离),然后在线程中调用一个设置分离属性的函数,那么这个线程就变成分离的属性。
1)设置线程本身的属性为分离属性。 -> pthread_detach() -> man 3 pthread_detach

#include <pthread.h>
int pthread_detach(pthread_t thread);

函数作用:
设置分离属性给线程
参数:
thread:需要设置分离属性的线程的ID号
返回值:
成功:0
失败:非0错误码
2)获取线程的ID号。 -> pthread_self() -> man 3 pthread_self

#include <pthread.h>
pthread_t pthread_self(void);

参数:

返回值:线程的ID号。

案例

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>//子线程
void *start_pthread(void *arg)
{int cnt = 0;//获取线程IDpthread_t thread_id = pthread_self();//分离线程int ret = pthread_detach(thread_id);if(ret != 0){printf(" pthread_detach fail\n");exit(0);}printf("arg:%ld\n", *((unsigned long *)arg));}int main(void)
{unsigned long val = 0;pthread_t  thread_id;//主线程 运行时间比子线程时间长,主线程运行退出后,回收子线程资源while (1){//线程创建 默认为非分离int ret = pthread_create(&thread_id, NULL, start_pthread, &val);if(ret != 0){printf("pthread_create fail\n");return -1;}    val++;}return 0;}

在这里插入图片描述
设置了分离属性之后,子线程可以无限被创建。

http://www.lryc.cn/news/323918.html

相关文章:

  • Leetcode 208. 实现 Trie (前缀树)
  • 蓝桥杯练习题——健身大调查
  • React——组件通讯
  • php闭包应用
  • 基于python+vue的OA公文发文管理系统flask-django-php-nodejs
  • 脉冲变压器电感的工艺结构原理及选型参数总结
  • java中Arrays介绍及常用方法
  • CTF题型 Http请求走私总结Burp靶场例题
  • Nginx 的安装、启动和关闭
  • python 操作excel(openpyxl.load_workbook)、excel操作封装
  • MySQL系统参数配置实战:生产环境优化
  • 判断列表中每一个元素的个数
  • 目标检测——PP-YOLOE算法解读
  • 每日一题 --- 螺旋矩阵 II[力扣][Go]
  • C语言自定义类型结构体
  • 【SpringBoot框架篇】37.使用gRPC实现远程服务调用
  • 投资的三个匹配
  • [Netty实践] 请求响应同步实现
  • Java进阶—哈希冲突的解决
  • css的border详解
  • 如何保障消息一定能发送到RabbitMQ?
  • 【web前端】CSS语法
  • JS+CSS3点击粒子烟花动画js特效
  • docker镜像复制与常见命令
  • 如何在linux环境上部署单机ES(以8.12.2版本为例)
  • 如何利用人工智能技术实现企业营销效率提升10倍(下)
  • 【PHP + 代码审计】数组函数
  • Keepalive与idle监测及性能优化
  • DS-红黑树(RBTree)
  • ubuntu 如何使用阿里云盘