【Linux系统编程】31.pthread_detach、线程属性

devtools/2024/10/18 14:24:01/

目录

pthread_detach

参数pthread

返回值

测试代码1

测试结果

pthread_attr_init

参数attr

返回值

pthread_attr_destroy

参数attr

返回值

pthread_attr_setdetachstate

参数attr

参数detachstate

返回值

测试代码2

测试结果

线程使用注意事项

pthread_detach

       实现线程分离。线程分离状态:指定该状态,线程主动与主控线程断开关系。线程结束后,其退出状态不由其他线程获取,而直接自己自动释放。网络、多线程服务器常用。

man 3 pthread_detach

参数pthread

待分离的线程ID。

返回值

成功:0

失败:错误号

测试代码1

分离一个线程,并回收。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <string.h>void *HuiDiao_HanShu(void *arg)
{printf("这是子线程的回调函数,子线程的进程ID是%d,子线程ID是%lu。\n", getpid(), pthread_self());return (void *)0;
}int main(int argc, char *argv[])
{int flag;pthread_t ZiXianCheng_ID; //子线程IDvoid *num = NULL;flag = pthread_create(&ZiXianCheng_ID, NULL, HuiDiao_HanShu, NULL); //创建子线程if (flag != 0){printf("创建子线程错误:%s\n", strerror(flag));exit(1);}printf("这是主线程,进程ID是%d,线程ID是%lu。\n", getpid(), pthread_self());printf("开始分离子线程!\n");flag = pthread_detach(ZiXianCheng_ID);if (flag != 0){printf("分离子线程错误:%s\n", strerror(flag));exit(1);}printf("分离子线程完成!\n");printf("这是主线程,先睡一会,再回收子线程!\n");sleep(1);printf("这是主线程,睡醒了!\n");printf("开始回收子线程!\n");flag = pthread_join(ZiXianCheng_ID, &num);if (flag != 0){printf("回收子线程错误:%s\n", strerror(flag));exit(1);}printf("回收子线程完成!\n");printf("num=%d\n", (int)num);pthread_exit(NULL);return 0;
}

测试结果

分离后的子线程结束后,会自动清理PCB,无需回收。

pthread_attr_init

初始化线程属性。

man 3 pthread_attr_init

参数attr

传出参数的属性。

返回值

成功:0

失败:错误号

pthread_attr_destroy

销毁线程属性所占用的资源。

man 3 pthread_attr_destroy

参数attr

传出参数的属性。

返回值

成功:0

失败:错误号

pthread_attr_setdetachstate

设置线程属性。

man 3 pthread_attr_setdetachstate

参数attr

已初始化的线程属性。

参数detachstate

分离线程:PTHREAD_CREATE_DETACHED

非分离线程:PTHREAD _CREATE_JOINABLE

返回值

成功:0

失败:错误号

测试代码2

设置线程的属性为分离属性,再回收子进程。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <string.h>void *HuiDiao_HanShu(void *arg)
{printf("这是子线程的回调函数,子线程的进程ID是%d,子线程ID是%lu。\n", getpid(), pthread_self());return (void *)0;
}int main(int argc, char *argv[])
{int flag;pthread_t ZiXianCheng_ID;         //子线程IDpthread_attr_t XianCheng_ShuXing; //线程属性void *num = NULL;flag = pthread_attr_init(&XianCheng_ShuXing); //初始化线程属性if (flag != 0){printf("线程属性初始化错误:%s\n", strerror(flag));exit(1);}flag = pthread_attr_setdetachstate(&XianCheng_ShuXing, PTHREAD_CREATE_DETACHED); //设置线程属性为分离属性if (flag != 0){printf("设置线程属性错误:%s\n", strerror(flag));exit(1);}flag = pthread_create(&ZiXianCheng_ID, &XianCheng_ShuXing, HuiDiao_HanShu, NULL); //创建子线程,借助线程属性将子进程分离if (flag != 0){printf("创建子线程错误:%s\n", strerror(flag));exit(1);}flag = pthread_attr_destroy(&XianCheng_ShuXing); //销毁线程属性if (flag != 0){printf("线程属性销毁错误:%s\n", strerror(flag));exit(1);}printf("这是主线程,进程ID是%d,线程ID是%lu。\n", getpid(), pthread_self());printf("这是主线程,先睡一会,再回收子线程!\n");sleep(1);printf("这是主线程,睡醒了!\n");printf("开始回收子线程!\n");flag = pthread_join(ZiXianCheng_ID, &num);if (flag != 0){printf("回收子线程错误:%s\n", strerror(flag));exit(1);}printf("回收子线程完成!\n");printf("num=%d\n", (int)num);pthread_exit(NULL);return 0;
}

测试结果

说明子线程已被成功分离,无需回收。

线程使用注意事项

  1. 主线程退出其他线程不退出,主线程应调用 pthread_exit。

  2. 避免僵尸线程,被join线程可能在join函数返回前就释放完自己的所有内存资源,所以不应当返回被回收线程栈中的值。

  3. malloc和mmap申请的内存可以被其他线程释放。

  4. 应避免在多线程模型中调用fork除非马上exec,子进程中只有调用fork的线程存在,其他线程在子进程中均 pthread_exit。

  5. 信号的复杂语义很难和多线程共存,应避免在多线程引入信号机制。


http://www.ppmy.cn/devtools/28575.html

相关文章

万兴PDF专家 PDFelement Pro v10.3.8 破姐版!

&#x1f9d1;‍&#x1f4bb;万兴PDF专家 PDFelement Pro v10.3.8 破姐版 (https://docs.qq.com/sheet/DRVVxTHJ3RXJFVHVr)

FreeBSD下安装Linux兼容系统Ubuntu

FreeBSD有个很神奇的功能&#xff0c;就是跟Linux二进制兼容&#xff0c;也就是可以直接运行linux的bin文件。还有个更神奇的功能&#xff0c;就是能运行出一套Linux系统&#xff0c;完全是linux的用户&#xff0c;linux的目录系统&#xff0c;而且还可以选是Centos系统还是Ubu…

TCP案例之单聊与群聊

TCP案例之单聊与群聊 一、TCP案例之单聊 在基于TCP协议的单聊应用中&#xff0c;通常涉及客户端和服务器端的交互。 服务器端 建立服务器&#xff1a; 服务器端创建一个TCP Socket并绑定到一个特定的端口&#xff0c;开始监听来自客户端的连接请求。 接受连接&#xff1a; …

kafka 线上消费积压问题

背景 线上kafka 流量大&#xff0c;消费小于生产&#xff0c;如何处理&#xff1f; 方案 增加consumer数量 可以增加consumer的消费者&#xff0c;不过这个只能在一定程序上缓解&#xff0c;如果consumer 数量超过partition 数&#xff0c;那有的就会空转&#xff0c;解决不…

速盾:高防cdn-为您的网站防御cc/ddos

随着互联网的飞速发展&#xff0c;网站安全问题也日益突出。网站被黑客攻击的事件频频发生&#xff0c;给用户和网站运营商带来了巨大的损失。其中&#xff0c;CC攻击和DDoS攻击是最常见的攻击手段之一。为了有效应对这些攻击&#xff0c;提高网站的安全性&#xff0c;高防CDN成…

算法训练营day25

零、回溯算法理论 参考链接13.1 回溯算法 - Hello 算法 (hello-algo.com) 1.尝试与回退 之所以称之为回溯算法&#xff0c;是因为该算法在搜索解空间时会采用“尝试”与“回退”的策略。当算法在搜索过程中遇到某个状态无法继续前进或无法得到满足条件的解时&#xff0c;它会…

vue集成百度地图vue-baidu-map

文章目录 vue集成百度地图vue-baidu-map1. Vue Baidu Map文档地址2. 设置npm数据源3. 安装vue-baidu-map4. 配置vue-baidu-map4.1 main.js全局注册4.2 vue页面设置4.3 效果 vue集成百度地图vue-baidu-map 1. Vue Baidu Map文档地址 https://dafrok.github.io/vue-baidu-map/#…

【c++】反向迭代器的探究实现

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;c笔记仓 在list中我们实现了正向的迭代器&#xff0c;学习完优先级队列后&#xff0c;我们也对适配器模式有了一个深刻的理解&#xff0c;这篇文章基于这种模式下&#xff0c;实现各类容器的反向迭…