012 Linux_线程控制

前言

本文将会向你介绍线程控制(创建(请见上文),终止,等待,分离)

线程控制

线程终止

pthread_t pthread_self(void); 获取线程自身的ID
在这里插入图片描述

在这里插入图片描述

如果需要只终止某个线程而不终止整个进程,可以有三种方法:
1. 从线程函数return。这种方法对主线程不适用,从main函数return相当于调用exit。
2. 线程可以调用pthread_ exit终止自己。
3. 一个线程可以调用pthread_ cancel终止同一进程中的另一个线程 若是在线程中使用exit()退出,整个进程都会退出

#include <vector>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
#include <iostream>
std::string ToHex(pthread_t tid)
{
    char id[64];
    snprintf(id, sizeof(id), "0x%x", tid);
    return id;
}
void *threadRoutine(void *args)
{
    std::string name = static_cast<const char*>(args);
    int cnt = 3;
    while(cnt--)
    {
        std::cout << "new thread is running, thread name: " << name << " ,thread id: " << ToHex(pthread_self()) << std::endl;
        sleep(1);
    }
    //return nullptr;	//线程退出
    //exit(13); 	//进程退出
    pthread_exit(nullptr);	//线程退出
    std::cout << "The thread ended ago" << std::endl;
}
int main()
{
    pthread_t tid;
    pthread_create(&tid, nullptr, threadRoutine, (void*)"thread-1");
    while(true)
    {
        std::cout << "main: The new thread id is: " <<  ToHex(tid) << std::endl;
        sleep(1);
    }
    return 0;
}

return nullptr:
在这里插入图片描述

exit():
在这里插入图片描述
pthread_exit(nullptr):
在这里插入图片描述
pthread_ cancel:
在这里插入图片描述

线程等待

为什么需要线程等待?
已经退出的线程,其空间没有被释放,仍然在进程的地址空间内。
创建新的线程不会复用刚才退出线程的地址空间

在这里插入图片描述

1. 如果thread线程通过return返回,value_ ptr所指向的单元里存放的是thread线程函数的返回值。
2. 如果thread线程被别的线程调用pthread_ cancel异常终掉,value_ ptr所指向的单元里存放的是常数 (-1)PTHREAD_ CANCELED。
3. 如果thread线程是自己调用pthread_exit终止的,value_ptr所指向的单元存放的是传给pthread_exit的参数。
4. 如果对thread线程的终止状态不感兴趣,可以传NULL给value_ ptr参数

这里只证实后3、4两个结论


#include <vector>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
#include <iostream>

void *threadRoutine(void *args)
{
    std::string name = static_cast<const char*>(args);
    int cnt = 3;
    while(cnt--)
    {
        std::cout << "new thread is running, thread name: " << name << " ,thread id: " << ToHex(pthread_self()) << std::endl;
        sleep(1);
    }
    
    //----------------------------------------------------------线程退出
    pthread_exit((void*)"thread-1 over...");
    std::cout << "The thread ended ago" << std::endl;
}

int main()
{
    pthread_t tid;
    pthread_create(&tid, nullptr, threadRoutine, (void*)"thread-1");
     void *ret = nullptr;
     int n = pthread_join(tid, &ret);
     std::cout << "main thread done" << " ,n: " << n << "info: " << "," << (char*)ret << std::endl;
    return 0;
}

在这里插入图片描述

//等待新线程结束并获取新线程退出的信息(获取新线程退出时的ID、信息、以及退出码)
#include <vector>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
#include <iostream>
class ThreadReturn
{
public:
    ThreadReturn(pthread_t id, const std::string &info, int code)
        : _id(id)
        , _info(info)
        , _code(code)
    {}
public:
    pthread_t _id;	//线程ID
    std::string _info;	//信息
    int _code;	//返回码
};
//十六进制转换
std::string ToHex(pthread_t tid)
{
    char id[64];
    snprintf(id, sizeof(id), "0x%x", tid);
    return id;
}
//线程任务
void *threadRoutine(void *args)
{
    std::string name = static_cast<const char*>(args);
    int cnt = 3;
    while(cnt--)
    {
        std::cout << "new thread is running, thread name: " << name << " ,thread id: " << ToHex(pthread_self()) << std::endl;
        sleep(1);
    }
    //pthread_exit((void*)"thread-1 over...");
    ThreadReturn *ret = new ThreadReturn(pthread_self(), "thread quit normal", 6);
    return ret;
}
int main()
{
    pthread_t tid;
    //创建线程
    pthread_create(&tid, nullptr, threadRoutine, (void*)"thread-1");
    void *ret = nullptr;
    //线程等待
    int n = pthread_join(tid, &ret);
    std::cout << "main thread done" << " ,n: " << n << std::endl;
    //安全类型转换
    ThreadReturn *r = static_cast<ThreadReturn *>(ret);
    //输出新线程退出时的参数信息
    std::cout << "main thread get new thread info:" << r->_info << ", " << r->_code << ", " << ToHex(r->_id) << ", " << std::endl;
    delete r;
    return 0;
}

在这里插入图片描述

线程分离

在这里插入图片描述

#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
int gcnt = 3;
void *ThreadRoutine(void *arg)
{
    pthread_detach(pthread_self());
    const char *threadname = (const char *)arg;
    while(true)
    {
        std::cout<< "I am a new thread" << std::endl;
        gcnt--;
        sleep(1);
    }
}
int main()
{
    pthread_t tid1;
    pthread_create(&tid1, NULL, ThreadRoutine, (void*)"thread 1");
    sleep(1);
    if ( pthread_join(tid1, NULL ) == 0 ) 
    {
      std::cout << "pthread wait success\n" << std::endl;
    } 
    else 
    {
      std::cout << "pthread wait failed\n"<< std::endl;
    }
    int n = pthread_cancel(tid1);
    std::cout << "main thread cancel done, " << "n: " << n << std::endl;
    return 0;
}

现象:
线程如果是被分离的,该线程是可以被取消,但是不能被等待
在这里插入图片描述

小结

今日的分享就到这里啦,如果本文存在疏漏或错误的地方还请您能够指出!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/429754.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SparkShop开源可商用,匹配小程序H5和PC端带分销功能!

SparkShop(星火商城)B2C商城是基于thinkphp6 elementui的开源免费可商用的高性能商城系统&#xff1b;包含小程序商城、H5商城、公众号商城、PC商城、App&#xff0c;支持页面diy、秒杀、优惠券、积分、分销、会员等级。营销功能采用插件化的方式方便扩展、二次开发 源码下载…

表单验证、属性绑定(一个属性根据另一个属性有无进行操作)

表单验证 一个属性根据另一个属性有无进行操作&#xff08;属性绑定&#xff09; 1、问题描述 ​ 需求&#xff1a;表单里面后两个属性需要根据前面一个属性进行有无判断。如果前面属性没有输入值&#xff0c;则不需要进行操作&#xff1b;如果前面属性有输入值&#xff0c;则…

Docker Swarm全解析:实现微服务高可用与故障转移的秘密武器

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《Docker入门到精通》 《k8s入门到实战》&#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、基本概念和介绍 1、Docker Swarm 是什么&#xff0c;它与 …

Rabbitmq消息丢失-消费者消息丢失(二)

说明&#xff1a;消费端在处理消息的过程中出现异常&#xff0c;例如&#xff1a;业务逻辑异常&#xff0c;或者消费者被停机&#xff0c;或者网络断开连接等&#xff0c;以上等情况使消息没有得到正确恰当的处理&#xff0c;也会使消息丢失。 分析&#xff1a;分析就是说明中…

【MATLAB第97期】基于MATLAB的贝叶斯Bayes算法优化BiGRU双向门控循环单元的多输入单输出回归预测模型,含GRU与BiGRU多层结构优化选择

【MATLAB第97期】基于MATLAB的贝叶斯Bayes算法优化BiGRU双向门控循环单元的多输入单输出回归预测模型&#xff0c;含GRU与BiGRU结构层数优化 前言 前面在【MATLAB第10期】讲解了基于贝叶斯Bayes算法优化LSTM长短期记忆网络的多输入单输出回归预测模型。 本次模型难点包括&am…

Ps:图案图章工具

图案图章工具 Pattern Stamp Tool可将各种预设图案或自定义的图案&#xff0c;通过画笔涂抹的方式填充到图像中。 快捷键&#xff1a;S 图案图章工具提供了一种快速、灵活的方式来为图像局部添加纹理和装饰。 这个工具类似于仿制图章工具&#xff0c;但区别在于&#xff0c;它使…

初阶数据结构:二叉树(补充扩展)

目录 1. 堆排序1.1补充&#xff1a;建堆的时间复杂度1.2 堆排序&#xff1a;升序与降序 2. TopK问题3. 二叉树的链式结构及其遍历方式3.1 二叉树的链式结构3.2 二叉树的前序遍历2.2 二叉树的中序遍历2.3 后序遍历2.4 层序遍历 4. 二叉树OJ练习4.1 单值二叉树4.2 判断两棵二叉树…

three.js如何实现简易3D机房?(一)基础准备-上

目录 一、tips 二、功能说明 1.模型初始化 2.功能交互 三、初始化准备 1.目录结构 2.创建三要素 3.创建轨道控制器 4.初始化灯光 5.适配 6.循环渲染 一、tips 1.three.js入门的相关基础性知识就不在此过多赘述了&#xff0c;可以自行提前了解 three.js docs&…

PyTorch深度学习实战(38)——StyleGAN详解与实现

PyTorch深度学习实战&#xff08;38&#xff09;——StyleGAN详解与实现 0. 前言1. StyleGAN1.1 模型介绍1.2 模型策略分析 2. 实现 StyleGAN2.1 生成图像2.2 风格迁移 小结系列链接 0. 前言 StyleGAN (Style-Generative Adversarial Networks) 是生成对抗网络 (Generative Ad…

基于Docker部署本地ChatGPT环境

基于Docker部署本地ChatGPT环境 一、拉取镜像 docker pull pengzhile/pandora二、运行镜像 docker run -e PANDORA_CLOUDcloud -e PANDORA_SERVER0.0.0.0:8899 -p 8899:8899 -d pengzhile/pandora三、查看容器是否启动成功 docker ps四、登录 http://IP:8899 这里有两种方…

原始手写helloworld并打jar包允许

1.创建文件夹test统一在其中操作 2.创建hello.java文件 【hello.txt改属性为hello.java】并在里面添加代码 public class hello {public static void main(String[] args) {System.out.println("hello world");} } 注意&#xff1a;类名与文件名一致 然后运行…

使用AI创建令人惊叹的3D模型

老子云平台《《《《《 使内容创作者能够在一分钟内毫不费力地将文本和图像转换为引人入胜的 3D 资产。 文本转 3D 我们的文本转 3D 工具使创作者&#xff08;包括那些没有 3D 经验的创作者&#xff09;能够使用文本输入在短短一分钟内生成 3D 模型。 一句话生成3D模型 老子…

FPGA-VGA成像原理与时序

什么是VGA: VGA, Video Graphics Array。即视频图形阵列,具有分辨率高、显示速率快、颜色丰富等优点。VGA接口不但是CRT显示设备的标准接口,同样也是LCD液晶显示设备的标准接口,具有广泛的应用范围。在FGPA中,常广泛用于图像处理等领域。 VGA 显示器成像原理 在 VGA 标准刚兴…

Material UI 5 学习02-其它按钮组件

Material UI 5 学习02-其它按钮组件 一、IconButton按钮二、 ButtonGroup按钮组1、最基本的实例2、垂直按钮组 一、IconButton按钮 图标按钮通常适用于切换按钮&#xff0c;允许选择或选择单个选项 取消选择&#xff0c;例如在项目中添加或删除星号。 <IconButton aria-lab…

docker pull 拉取失败,设置docker国内镜像

遇到的问题 最近在拉取nginx时&#xff0c;显示如下错误&#xff1a;Error response from daemon: Get “https://registry-1.docker.io/v2/”: net/http: request canceled (Client.Timeout exceeded while awaiting headers)。 这个的问题是拉取镜像超时&#xff0c;通过检索…

RISC-V特权架构 - 机器模式下的异常处理

RISC-V特权架构 - 机器模式下的异常处理 1 进入异常1.1 从mtvec 定义的PC 地址开始执行1.2 更新CSR 寄存器mcause1.3 更新CSR 寄存器mepc1.4 更新CSR 寄存器mtval1.5 更新CSR 寄存器mstatus 2 退出异常2.1 从mepc 定义的PC 地址开始执行2.2 更新CSR 寄存器mstatus 3 异常服务程…

Docker Protainer可视化平台,忘记登录密码,重置密码。

由于好久没有登录portainer系统&#xff0c;导致忘记了登录密码&#xff0c;试了好多常用的密码都不对&#xff0c;无奈只能重置密码。 一、停止protainer 容器 查看容器ID和COMMAND 用于停止容器 docker ps -a停止容器 docker stop portainer二、查找volume data 宿主机所在…

脉冲电阻器负载、功率和电压降额,选型分析

本文讨论了关键的电阻脉冲负载、功率和电压降额参数&#xff0c;这些参数对于正确选择指南和可靠运行这些无源元件非常重要。 EAK脉冲负载 在许多应用中&#xff0c;电阻器将承受脉冲负载。我们区分周期性/重复性负载和脉冲序列;一方面&#xff0c;脉冲以一定频率重复&#xff…

Spring中最常用的11个扩展点

前言 我们一说到spring&#xff0c;可能第一个想到的是 IOC&#xff08;控制反转&#xff09; 和 AOP&#xff08;面向切面编程&#xff09;。 没错&#xff0c;它们是spring的基石&#xff0c;得益于它们的优秀设计&#xff0c;使得spring能够从众多优秀框架中脱颖而出。 除…

Thingsboard本地源码部署教程

本章将介绍ThingsBoard的本地环境搭建&#xff0c;以及源码的编译安装。本机环境&#xff1a;jdk11、maven 3.6.2、node v12.18.2、idea 2023.1、redis 6.2 环境安装 开发环境要求&#xff1a; Jdk 11 版本 &#xff1b;Postgresql 9 以上&#xff1b;Maven 3.6 以上&#xf…