【Linux】C语言中多线程的创建、退出、回收、分离

news2024/11/13 18:12:47

概述

线程是轻量级的进程(LWP:light weight process),在 Linux 环境下线程的本质仍是进程。在计算机上运行的程序是一组指令及指令参数的组合,指令按照既定的逻辑控制计算机运行。操作系统会以进程为单位,分配系统资源,可以这样理解,进程是资源分配的最小单位,线程是操作系统调度执行的最小单位

在Linux系统下,线程的创建和管理是通过pthread库实现的。pthread是POSIX线程库,提供了创建、终止、同步和通信线程的函数和数据结构。

创建线程

线程函数

每一个线程都有一个唯一的线程 ID,ID 类型为 pthread_t,这个 ID 是一个无符号长整形数,如果想要得到当前线程的线程 ID,可以调用如下函数:

pthread_t pthread_self(void);	// 返回当前线程的线程ID

在Linux系统下,可以使用pthread_create函数来创建线程。pthread_create函数的原型如下:

#include <pthread.h>

int pthread_create(pthread_t* thread, const pthread_attr_t* attr, void* (*start_routine)(void*), void* arg);

  • thread:指向pthread_t类型的指针,用于存储新创建线程的标识符。在成功创建线程后,该指针将被填充为一个唯一的标识符,用于后续对线程的引用。
  • attr:指向pthread_attr_t类型的指针,用于指定线程的属性。线程属性对象可以控制线程的各种行为,例如线程的调度策略、栈大小、分离状态等。如果不需要对线程属性进行特殊设置,可以传入NULL,使用默认属性。
  • start_routine:指向线程函数的指针,该函数是线程的入口点。线程函数是线程的实际执行体,当线程被创建时,将从该函数开始执行。函数的返回类型必须为void*,并接受一个void*类型的参数。线程函数可以执行任意操作,包括计算、访问共享资源等。
  • arg:传递给线程函数的参数,类型为void*。可以将任意类型的数据传递给线程函数,只需将其转换为void*类型。在线程函数内部,可以使用适当的类型转换将参数恢复为原始类型。

返回值:线程创建成功返回 0,创建失败返回对应的错误号

在编写多线程程序的时候,如果想要让线程退出,但是不会导致虚拟地址空间的释放(针对于主线程),我们就可以调用线程库中的线程退出函数,只要调用该函数当前线程就马上退出了,并且不会影响到其他线程的正常运行,不管是在子线程或者主线程中都可以使用。

void pthread_exit(void *retval);

参数 retval 是一个指向任意类型的指针,表示线程的退出状态。线程的退出状态可以用于与其他线程进行通信或传递结果。

pthread_self() 是一个 POSIX 线程库函数,用于获取当前线程的线程 ID。

pthread_t pthread_self(void);

线程创建

注意:线程函数可以接受一个指向任意类型的参数,并且返回一个指向任意类型的指针。
首先使用vim pthread_create.c创建c语言文件。
键入代码:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<pthread.h>

void *callback(void* arg)
{
        for(int i=0;i<5;++i)
                {
                        printf("子线程:i=%d\n",i);

                }
        printf("子线程:%ld\n",pthread_self());
        return NULL;
}

int main()
{
        pthread_t tid;
        pthread_create(&tid,NULL,callback,NULL);
        for(int i=0;i<5;++i)
        {
                printf("主线程:i=%d\n",i);
        }
        printf("主线程:%ld\n",pthread_self());
        pthread_exit(NULL);
        return 0;
}

保存文件后使用g++ pthread_create.c -lpthread -o app命令进行编译。
该命令用于编译名为 pthread_create.c 的源代码文件,并链接 pthread 库生成可执行文件 app。

g++:是 GNU 编译器集合中的 C++ 编译器。
pthread_create.c:是要编译的源代码文件的名称。
-lpthread:表示链接 pthread 库,这是 POSIX 线程库。
-o app2:指定生成的可执行文件的名称为 app2

在这里插入图片描述
执行./app,结果如下所示
在这里插入图片描述

线程回收

在线程编程中,线程回收是指等待线程执行结束并收回相关资源。在 POSIX 线程库中,可以使用 pthread_join 函数来实现线程的回收。pthread_join 函数的原型如下:

int pthread_join(pthread_t thread, void **retval);

其中,thread 参数是要回收的线程标识符,retval参数用于接收线程的返回值。函数的返回值表示回收线程的执行状态,如果成功回收线程,则返回 0,否则返回一个非零值,表示出现了错误。

当调用 pthread_join 函数时,当前线程会被阻塞,直到指定的线程执行结束。一旦线程执行结束,它的资源将被回收,并可以通过 retval 参数获取线程的返回值。

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<pthread.h>
struct persion
{
int num;
int age;
};
void *callback(void* arg)
{
        for(int i=0;i<5;++i)
                {
                        printf("子线程:i=%d\n",i);

                }
        printf("子线程:%ld\n",pthread_self());
        struct persion* t = (struct persion*)arg;
        t->num=100;
        t->age=5;
        pthread_exit(&t);
        return NULL;
}

int main()
{
        pthread_t tid;
        struct persion t;
        pthread_create(&tid,NULL,callback,&t);
        for(int i=0;i<5;++i)
        {
                printf("主线程:i=%d\n",i);
        }
        printf("主线程:%ld\n",pthread_self());
        void *ptr;
        pthread_join(tid,&ptr);
        struct persion *pt=(struct persion*)ptr;
        printf("num:%d,age:%d\n",t.num,t.age);
        pthread_exit(NULL);
        return 0;
}

pthread_join其实是个阻塞函数,如果还有子线程在运行,调用该函数就会阻塞,子线程退出函数解除阻塞进行资源的回收,函数被调用一次,只能回收一个子线程,如果有多个子线程则需要循环进行回收。

ptr 用于接收子线程的返回值,pt 通过强制类型转换指向子线程的返回值,而 t 是主线程中的一个独立对象

结果如下所示:
在这里插入图片描述

线程分离

线程的分离是指将线程设置为分离状态,使其在退出时自动释放资源,不需要显式地调用 pthread_join 函数来等待线程的结束。

在某些情况下,程序中的主线程有属于自己的业务处理流程,如果让主线程负责子线程的资源回收,调用 pthread_join() 只要子线程不退出主线程就会一直被阻塞,主要线程的任务也就不能被执行了。

线程分离之后在主线程中使用 pthread_join() 就回收不到子线程资源了。

        for(int i=0;i<5;++i)
                {
                        printf("子线程:i=%d\n",i);

                }
        printf("子线程:%ld\n",pthread_self());
        struct persion* t = (struct persion*)arg;
        t->num=100;
        t->age=5;
        pthread_exit(&t);
        return NULL;
}

int main()
{
        pthread_t tid;
        struct persion t;
        pthread_create(&tid,NULL,callback,&t);
        for(int i=0;i<5;++i)
        {
                printf("主线程:i=%d\n",i);
        }
        printf("主线程:%ld\n",pthread_self());
        pthread_detach(tid);
        pthread_exit(NULL);

        return 0;
}

线程分离后,子线程执行完毕后被系统内核回收了,且主线程退出后不会影响子线程的执行。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Spring AOP】面向切面编程

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔&#x1f93a;&#x1f93a;&#x1f93a; 目录 1. 什么是Spring AOP&#xff1f; 2. 为什么要…

NFC type 12345 tag介绍

NFC(近场通信)被称为短距离无线技术&#xff0c;是一套通信协议&#xff0c;NFC技术将非接读卡器/Reader、非接标签/Tag和点对点(Peer-to-Peer)数据交换的功能设计融为一体!使电子设备之间能够进行简单、安全的双向交互。为推动NFC技术发展&#xff0c;2004年&#xff0c;诺基亚…

Stable-Diffusion环境搭建

硬件可以采用DELL R7525 搭配L4 或者T4 等等企业级显卡 环境如下&#xff1a; 可以看到有相应的GPU卡信息 esxi 7.u3 信息 设置GPU穿透方式 查看相应的虚拟机参数信息 PCI 设备加载穿透GPU信息 启动uefi 设置相应的参数信息 https://docs.nvidia.com/grid/latest/grid-vgpu-re…

如何检测视频中的绿屏、绿帧问题

今天给项目拷机&#xff0c;发现视频会偶现绿屏&#xff0c;非常偶现&#xff0c;很难复现出来。 由于问题暂时没有定位&#xff0c;只能先表面解决一下&#xff0c;就是过滤掉出现绿屏的帧。 当然&#xff0c;首先要把绿帧检测出来&#xff0c;才能做后续的补救措施。 绿屏、…

电感公式推导

目录 电感的磁感应强度用&#xff1a;B表示 加入磁芯的可以提高磁感应强度&#xff1a;BμNI &#xff08;μ > μ0&#xff09; 磁芯的磁通量用&#xff1a;Φ来表示 一匝线圈感生电动势用&#xff1a;E来表示 在整个电感线圈的里面产生的感生电动势用UL来表示&#xff…

软件测试项目实战,电商项目核心业务测试分析(全覆盖)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 登陆功能怎么测试…

第16章_多版本并发控制

第16章_多版本并发控制 1. 什么是MVCC MVCC(Multiversion Concurrency Control)&#xff0c;多版本并发控制。顾名思义&#xff0c;MVCC是通过数据行的多个版本管理来实现数据库的并发控制。这项技术使得在InnoDB的事务隔离级别下执行一致性读操作有了保证。换言之&#xff0…

chapter9: SpringBoot自定义Starter

尚硅谷SpringBoot顶尖教程 1. 自定义starter介绍 自定义starter从下面两个方面着手&#xff1a; 这个自定义starter的场景需要用到哪些依赖&#xff1f;如何编写自定义starter的自动配置&#xff1f; 查看springboot提供的已有starter组件的自动配置类&#xff0c;基本使用…

NFC Forum Type2 Tag

RC522作为一款NFC读写芯片&#xff0c;性价比还是很高的&#xff0c;因为在项目里需要采用NFC OOB配对&#xff0c;所以需要读取配对方模拟的NFC卡片信息 读取对象采用NRF52832&#xff0c;使用其NFC功能模拟type2 tag&#xff0c;但是读取方式和M1卡不一样&#xff0c;踩了不…

软件测试员不要过于迷信技术,忽视软技能

精于技术对于测试员&#xff0c;乃至技术员本身没毛病&#xff0c;甚至应大加赞赏&#xff0c;在组织中更应像国宝熊猫一样照顾好。然而我们发现&#xff0c;一些精于技术的测试员混的并不好。“纯正”的技术人员就该吃亏&#xff1f;问题到底出现在哪里&#xff1f; 根据我对…

南大通用GBase 8c 多模多态分布式数据库系列二之安装与卸载

目录 一.前言 二. 学习目标 三. 安装流程 四. 配置要求 1. 硬件配置要求 2. 软件配置要求 3. 软件依赖配置 五. 集群规划 1. 物理规划 2. 演示环境配置 六. 安装前环境检查 1. 关闭防火墙 2. 关闭SELINUX 3. 主机名检查、依赖检查 4. Gbase用户配置sudo 七. 配…

科研闭环指南|关于 Review Rebuttal 的二三事

两个月前投稿的论文审稿&#xff08;Review&#xff09;意见快下来了&#xff0c;期间我也是作为审稿人&#xff08;Reviewer&#xff09;完成了4篇工作的审稿工作。回想自己从入学以来也算是审过 10 篇左右的稿子了&#xff0c;也参与过 Review 之后的 Rebuttal 环节。下面我就…

思维决定发展,软件测试人也不例外

最近特别懒&#xff0c;不想码字&#xff0c;原本写作就很差&#xff0c;更是退化严重。社招和校招面试过很多人&#xff0c;从十年前自己还很弱的时候学着面试&#xff0c;到数百次面试积累之后&#xff0c;面对候选人的时候&#xff0c;我的内心依然有些许紧张&#xff0c;非…

《Reinforcement Learning: An Introduction》第5章笔记

Chapter 5 Monte Carlo Methods Monte Carlo 方法不假设拥有完备的环境知识&#xff0c;它仅仅需要经验–从与环境的实际或模拟交互中得到的一系列的状态、动作、和奖励的样本序列。 Monte Carlo方法是基于平均采样回报的来解决强化学习问题的方法。 5.1 Monte Carlo Predic…

NFS服务器

文章目录 NFS服务器NFS的由来与功能什么是NFS(Network File System)什么是RPC(Remote Procedure Call)NFS启动的RPC daemons NFS Server 端的配置所需要的软件NFS的软件结构/etc/exports配置文件的语法与参数 启动NFSRPC服务的注册状况怎么查看(rpcinfo) NFS的连接查看showmoun…

认识服务器

1、查看操作系统的信息 CentOS 输入&#xff1a;cat /etc/os-release 字段含义解释NAME操作系统名称CentOS LinuxVERSION操作系统版本7 (Core)ID操作系统标识centosID_LIKE相关操作系统标识rhel fedoraVERSION_ID操作系统版本号7PRETTY_NAME可读性较好的操作系统名称CentOS L…

产品如何有效把控产品上线质量

很多人乍看这个标题&#xff0c;可能有些惊讶。产品上线质量不是由测试来主要负责的么&#xff0c;怎么产品也需要来把控这个事情&#xff1f; 诚然&#xff0c;从具体分工而言&#xff0c;产品的线上质量主要由测试来负责&#xff0c;产品按时按量完成由项目项目经理把控。但…

详谈数据中心网络中的四种虚拟化技术:VXLAN、NVGRE、STT和SPBM

概要 在现代的数据中心网络中&#xff0c;虚拟化技术被广泛应用以提供更高的可扩展性、灵活性和效率。数据中心网络虚拟化允许多个虚拟网络在共享的物理基础设施上运行&#xff0c;使得网络资源的管理更为简单和高效。本文将详细介绍数据中心网络中的四种不同类型的虚拟化技术&…

全网超全,接口测试用例设计——常见问题和风险,测试不背锅...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 接口测试用例设计…

【开源工具】使用Whisper提取视频、语音的字幕

这里写目录标题 一、语音转字幕操作步骤1、下载安装包Assets\WhisperDesktop.zip[^2]2、加载模型2.1 下载模型2.1.1 进入Hugging Face[^3]的仓库2.1.2 选择需要下载的模型2.1.3 配置模型路径 3、语音转字幕4、实时语言转录功能 二、相关简介[^1]特点开发人员指南构建说明其他注…