【Linux】详解线程控制之线程创建线程终止线程等待线程分离

一、线程创建

thread:这是一个指向pthread_t类型的指针,用于获取新创建线程的线程ID。在调用pthread_create后,这个指针会被设置为新线程的ID。

attr:这是一个指向pthread_attr_t类型的指针,用于设置线程的属性,如栈大小、优先级等。如果这个参数为NULL,那么线程将使用默认的属性。通常情况下,如果你不需要设置特殊的线程属性,可以传递NULL。

 

start_routine:这是一个函数指针,指向线程开始执行时要调用的函数。这个函数通常被称为线程的“入口点”或“启动例程”。

arg:用于向线程的启动例程传递参数。你可以通过这个参数向线程传递任何类型的数据。如果你的启动例程不需要任何参数,可以传递NULL。

二、线程终止

终止线程的三种方法:

  1. 在线程函数的内部使用return语句。
  2. 在线程函数的内部使用pthread_exit函数。
  3. 在主线程中使用pthread_cancel函数,可以回收指定的子线程。

2.1、pthread_exit函数

         pthread_exit函数中可以设置retval返回值,在主线程中可以调用pthread_join函数来获取子线程的返回值

2.2、pthread_cancel函数

        在主线程中使用pthread_cancel函数,在pthread_cancel函数中传入子进程的id可以直接终止子线程,不用等子线程跑完

2.3、注意点

不能用exit终止线程,因为exit是用来终止进程的,一旦exit执行了,那么整个进程也就退出了

三、线程等待回收

线程也要被等待回收,不然会出现类似于进程等待那里的僵尸问题,也就是出现内存泄漏。

        pthread_join函数可以用来回收子线程,第一个参数为子线程的id, 第二个参数可以得到子线程的退出信息。主线程退出整个进程就跟着退出了,也就意味着主线程退出所有线程都要跟着退出,所以我们一般需要主线程最后退出来等待回收子线程

四、线程创建、终止、回收的例子

        下面由主线程创建一批子线程,分配给子线程任务,子线程将结果封装起来并返回给主线程,主线程由此可以获取子线程的执行结果。

对任务进行封装,让子线程去执行加法任务:

class Task
{
private:
    int _x;
    int _y;
public:
    Task(int x, int y)
    :_x(x), _y(y)
    {}

    int Add()
    {
        return _x + _y;
    }
    ~Task()
    {}
};

分配给子线程任务,并回收结果:

#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <vector>
using namespace std;

class ThreadData
{
private:
    Task _t;
    string _name;
public:
    ThreadData(Task t, string name)
    :_t(t), _name(name)
    {}

    Task getTask()
    {
        return _t;
    }

    string getName()
    {
        return _name;
    }
    ~ThreadData()
    {}
};
//结果封装
class Res
{
private:
    int _result;
    string _name;
public:
    Res(int result, string name)
    :_result(result)
    ,_name(name)
    {}

    int getResult()
    {
        return _result;
    }

    string getName()
    {
        return _name;
    }
    ~Res()
    {}
};
//子线程执行的函数
void* handler(void* args)
{
    ThreadData* th = (ThreadData*)args;
    Res* res = new Res(th->getTask().Add(), th->getName());
    delete th;
    return res;
}

vector<pthread_t> vect_tid;
vector<Res*> vect_res;
int main()
{
    for(int i = 0; i<5; i++)
    {
        pthread_t tid;
        Task task(10, 20);
        char buffer[1024];
        snprintf(buffer, sizeof(buffer), "thread-%d", i+1);
        ThreadData* th = new ThreadData(task, buffer);
        pthread_create(&tid, nullptr, handler, th);
        vect_tid.push_back(tid);
    }

    for(auto& e : vect_tid)
    {
        void* ret = nullptr;
        pthread_join(e, &ret);
        vect_res.push_back((Res*)(ret));
    }

    for(auto& e : vect_res)
    {
        cout << e->getName() << " " << "res=" << e->getResult() << endl;
        delete e;
    }
    return 0;
}

五、线程分离

        线程被创建出来的时候默认是joinable的,也就是说需要被等待的。如果我们的主线程并不关心新线程的执行结果,我们可以将新线程设置为分离状态。所谓的分离只是进程的一种工作状态,在底层依旧数据共享,依旧属于同一个进程

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

void* handler(void* args)
{
    const std::string str = static_cast<const char*> (args);
    int cnt = 5;
    while(cnt--)
    {
        std::cout << str << std::endl;
        sleep(1);
    }

    return nullptr;
}

int main()
{
    pthread_t tid;
    pthread_create(&tid, nullptr, handler, (void*)"new Thread");
    //detach可以放在main函数中也可以放在handler函数中
    pthread_detach(tid);
    while(true)
    {}
    return 0;
}

        分离之后再主线程中就不需要再对子线程进行等待回收了,即不需要在主线程中调用pthread_join函数。

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

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

相关文章

网络工程师备考1——基础学习

认识设备 1 交换机 一、什么是交换机&#xff1f; 实现不同电脑之间数据的转发 换机是一种用于电(光)信号转发的网络设备。 它可以为接入交换机的任意两个网络节点提供独享的电信号通路。最常见的交换机是以太网交换机。交换机工作于OSI参考模型的第二层&#xff0c;即数据…

SpringBoot3整合阿里云短信服务-1(配置阿里云短信服务)

SpringBoot3整合阿里云短信服务-1(配置阿里云短信服务) 一、开通阿里云短信服务 阿里云官网:阿里云官网 选择产品中企业服务与云通信中的短信服务 选择免费开通 选择快速学习和测试 根据这几个全部配置一下我这里是配置好了所以学习进度是100% 1.1 添加资质 首先选择新增资质 …

SpringBoot发送邮箱

一、导入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId> </dependency> 二、添加配置 application.yml文件 将username修改为自己的邮箱&#xff0c;password修改为…

【Vue】Vue2使用ElementUI

目录 Element UI介绍特点Vue2使用Element安装引入ElementUI组件库 使用ElementUI用户注册列表展示其他 mint-ui介绍特点安装组件引入组件Mint-ui相关组件 Element UI 介绍 官网(基于 Vue 2.x ):https://element.eleme.cn/#/zh-CN ElementUI 是一个基于 Vue.js 的桌面端组件库…

基于Arduino的电梯超载报警系统

企鹅&#xff1a;2583550535 项目和论文都有 第1章 绪论.............................................................................................................................. 1 1.1 项目背景及意义........................................................…

ABP.VNET 项目结构

想要了解ABP分层架构&#xff1a;ABP分层架构-CSDN博客 可以看此篇文章 apb.vnet 生成的项目的目录结构 .Application 项目 应用服务用于将领域(业务)逻辑暴露给展现层。 展现层通过传入DTO(数据传输对象)参数来调用应用服务&#xff0c;而应用服务通过领域对象来执行相应的…

【网络安全】2030年十大新兴网络安全威胁

欧盟网络安全局&#xff08;ENISA&#xff09;已发布了一份全面的清单&#xff0c;列出了预计到2030年将影响数字领域的十大新兴网络安全威胁。 该预测是为期八个月的广泛研究的成果&#xff0c;融合了ENISA前瞻专家小组、CSIRTs网络以及欧盟CyCLONe专家的见解。 这项研究突显…

抖音小店无货源怎么做?从开店到发货,最全教程来了!

哈喽~我是电商月月 近几年&#xff0c;抖音的发展如火如荼&#xff0c;抖音小店也吸引了大批新手商家入驻 那抖音小店具体流程到底怎么做&#xff1f;无货源的商家去哪找货&#xff1f;怎么上架&#xff0c;如何推流? 不知道&#xff1f; 今天我就给大家讲一下抖音小店从开…

[集群聊天服务器]----(五)User类、UserModel类

接着上文[集群聊天服务器]----(四)MySQL数据库模块&#xff0c;接下来我们对User类、UserModel类进行剖析&#xff0c;User表和UserModel类是项目最基本也是最重要的部分&#xff0c;通过它我们对用户的id&#xff0c;用户名&#xff0c;密码&#xff0c;状态相关信息进行存储&…

数据分析【方差分析】四

方差分析的核心 什么是方差分析:方差分析是假设检验的一种延续与扩展,主要用于多个总体均值(三组或三组以上均值)是否相等做出假设检验,研究分类型自变量对数值型因变量的影响。 它的零假设和设备假设分别为: 单因素方差分析的前提条件 独立性 组内独立(随机抽样、…

<string.h>中部分库函数的模拟实现

前言 嗨&#xff0c;我是firdawn&#xff0c;本章将简单介绍&#xff0c;<string.h>中部分库函数的模拟实现&#xff0c;如strncpy&#xff0c;strncat&#xff0c;memcpy&#xff0c;memmove。在本文片末&#xff0c;还讲简单介绍判断机器大小端的函数实现&#xff0c;…

【Linux】LAMP集群分布式安全方案

LAMP集群分布式安全方案主要涉及确保Linux、Apache、MySQL和PHP&#xff08;LAMP&#xff09;组合构成的集群环境的安全性和稳定性。 本次实验通过网络层安全对防火墙配置&#xff1a;使用防火墙&#xff08;如iptables或firewalld&#xff09;来限制对集群的访问&#xff0c;只…

设计模式在芯片验证中的应用——单例

一、单例模式 单例模式(Singleton)是一种创建型设计模式&#xff0c;能够保证一个类只有一个实例&#xff0c; 并提供一个访问该实例的全局节点。验证环境配置(configuration)类、超时(timeout)处理类等可以使用单例实现。比如说验证环境需要在特定场景中监测特定接口上的超时事…

AI+BI?国内期待值最高的4款智能问答类BI产品测评

AI大模型的这股风终是吹到了数据分析圈。与传统BI相比&#xff0c;问答BI进一步降低了数据获取门槛&#xff0c;通过对话的方式就可以访问数据并得出相应结论&#xff0c;更方便业务人员快速上手分析数据&#xff01; 问答BI&#xff08;Q&A BI&#xff09;在数据分析领域…

【论文笔记】| 定制化生成PuLID

PuLID: Pure and Lightning ID Customization via Contrastive Alignment ByteDance, arXiv:2404.16022v1 Theme: Customized generation 原文链接&#xff1a;https://arxiv.org/pdf/2404.16022 Main Work 提出了 Pure 和 Lightning ID 定制 (PuLID)&#xff0c;这是一种用于…

LaTeX 2022软件安装教程(附软件下载地址)

软件简介&#xff1a; 软件【下载地址】获取方式见文末。注&#xff1a;推荐使用&#xff0c;更贴合此安装方法&#xff01; LaTeX 2022是基于ΤΕΧ的一种排版系统&#xff0c;特别适用于生成科技和数学文档的高质量打印。它可用于各种文档类型&#xff0c;从简单信函到完整…

使用DataGrip连接Elasticsearch

使用DataGrip连接Elasticsearch 前言&#xff0c;公司需要使用ES来做数据的查询&#xff0c;我安装完ES&#xff0c;安装完Kibana的时候&#xff0c;想先开始尝试一下&#xff0c;插入查询数据能否可用&#xff0c;但是上次使用ES是好久前了&#xff0c;增删改查的请求根本记不…

学习Nginx(十四):配置SSL/TLS支持HTTPS

概念 SSL/TLS&#xff1a;安全套接字层&#xff08;SSL&#xff09;及其继任者传输层安全性&#xff08;TLS&#xff09;是为网络通信提供安全及数据完整性的一种安全协议。它们通过在应用程序协议&#xff08;如HTTP&#xff09;与TCP/IP协议族之间提供数据加密封面&#xff…

Three.js 研究:1、如何让物体动起来

1、制作模型动画 2、模型动画在代码中的调用 使用这个例子进行修改&#xff0c;使他能动作webgl_animation_skinning_morph.html 制作好的模型放到如下路径 /three.js-master/examples/models/gltf/无标题.gltf修改加载模型文件的地址 修改动画名称 运行 点击动画后&…

Python TinyDB库:轻量级NoSQL数据库的终极指南

更多Python学习内容&#xff1a;ipengtao.com TinyDB是一个轻量级的NoSQL数据库&#xff0c;适用于需要嵌入式数据库的小型项目。它使用JSON文件存储数据&#xff0c;并提供了简单易用的API&#xff0c;支持多种查询和索引操作。TinyDB非常适合那些不需要复杂数据库功能的小型应…