线程控制(二)------线程等待、分离与结合属性

线程剖析(part2)—线程控制及线程属性 前言在博主的上一篇博客中讲述了线程的基本概念及线程创建,没有看过的小伙伴可以点击这里:linux线程剖析(part1)—1个“假”的tcb本篇博文将重点从两个方面:线程控制(线程等待、线程终止)及线程属性来进一步分析线程特点。线程终止首先,我们需要知道线程终止的几种方式:1.从线程函数中return(特殊:从main函数中return,代表进程退出,也代表主线程退出。那么此时线程必定被终止。) 2 阅读详情

线程等待

为什么需要线程的等待?

  • 已经退出的线程,其空间没有被释放,仍然在进程的地址空间。
  • 创建新的线程不会复用刚才退出线程的地址空间。
    这里写图片描述
    调用该函数的线程将挂起状态,直到id为thread的线程终止,thread线程以不同的方法终止,通过pthread_join得到的终止状态是不同的,总结如下:

1、 如果thread线程通过return返回,value_ptr所指向的单元里存放的是thread线程函数的返回值。
2、如果thread线程被别的线程调用pthread_cancel异常终掉,value_ptr所指向的单元里存放的是常数PTHREAD_CANCELED(为-1是void*类型的)。
3、如果thread线程是自己调用pthreadexit终止的,valueptr所指向的单元存放的是传给ptrread_exit的参数。
4、如果对thread线程的终止状态不感兴趣,可以传给NULL给value_ptr参数。

这里写图片描述
我们来看一个线程等待的例子:

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

void *thread1(void *arg)
{
    printf("thread 1 returning ...\n");
    int *p=(int*)malloc(sizeof(int));
    *p=1;
    return (void*)p;
}

void *thread2(void *arg)
{
    printf("thread 2 exiting  ...\n");
    int *p=(int*)malloc(sizeof(int));
    *p=2;
    pthread_exit((void*)p);
}

void *thread3(void *arg)
{
    while(1){
    printf("thread 3 is running ...\n");
    sleep(1);
    }
    return NULL;
}

int main()
{
    pthread_t  tid;
    void *ret;

     //thread 1  return
     pthread_create(&tid,NULL,thread1,NULL);
     pthread_join(tid,&ret);
     printf("thread return,thread id %x,return code:%d\n",tid,*(int*)ret);
     free(ret);


      //thread 2 exit
      pthread_create(&tid,NULL,thread2,NULL);
      pthread_join(tid,&ret);
      printf("thread return ,thread id %x,return code:%d\n",tid,*(int*)ret);
      free(ret);

      //thread 3 cancel by other
      pthread_create(&tid,NULL,thread3,NULL);
      sleep(3);
      pthread_cancel(tid);
      pthread_join(tid,&ret);
      if(ret==PTHREAD_CANCELED)
      {
     printf("thread return,thread id %x,return code:PTHREAD_CANCELED\n",tid);
      }
     else
     printf("thread return,thread id %x,return code:NULL\n",tid);
}

运行结果如下所示:

这里写图片描述

分离线程

默认情况线程是可结合的,代表的含义就是这个线程必须被等待。
- 默认情况下新创建的线程是joinable的,线程退出后,需要对其进行pthread_join操作,否则无法释放资源,从而造成系统柜的内存泄漏的问题。
- 如果不关心线程的返回值,join是一种负担,这个时候,我们可以告诉系统,当线程退出时,自动释放线程资源。
这里写图片描述
这个函数的作用是可以是线程组内其他线程对目标线程进行分离,也可以是线程自己进行分离。
这里写图片描述
joinable和分离是冲突的,一个线程不可能既是joinable也是分离的。
线程的分离状态决定了一个线程以什么样的方式来终止自己。在默认的情况下线程是非分离状态的,这种情况下,原有的线程等待创建的线程结束。只有当 pthread_join ()函数返回时,创建的线程才算终止,才能释放自己占有用的系统资源,而分离线程不是这样子的,它没有被其他的线程所等待,自己运行结束了,线程也就终止了,马上释放系统资源。程序员应该根据自己的需要,选择适当的分离状态,所以如果我们在创建线程时就知道不需要了解线程的终止状态,则可以 pthread_attr_t结构中,的detachstate线程属性,让线程以分离状态启动。
示例代码:

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


void *thread_run(void *arg)
{
    pthread_detach(pthread_self());
    printf("%s\n",(char*)arg);
    return NULL;
}


int main()
{
    pthread_t tid;
    if(pthread_create(&tid,NULL,thread_run,"thread1 run ...")!=0){
    printf("create thread error\n");
    return 1;
    }
    int ret=0;
    sleep(1);
    if(pthread_join(tid,NULL)==0){
    printf("pthread wait success\n");
    ret=0;
    }
    else{
    printf("pthread wait failed\n");
    ret=1;
    }
return ret;
}

结果如下:在子线程运行完毕后,分离tid后,查看是否能够等待成功,若不能则说明分离成功。
这里写图片描述

linux操作系统之线程 注意:一次pthread_create执行只能创建一个线程, 每个进程至少有一个线程称为主线程,主进程退出则所有创建的子线程都退出,主线程必须有子线程同时运行才算多线程程序,线程id是线程的唯一标识,是CPU维护的一组数字。参数:thread:存放线程ID空间首地址,attr:线程的属性(默认NULL),start_routine:线程入口函数地址(函数指针,指向线程任务函数),arg:给线程函数的参数。创建:线程空间位于进程空间,进程中的线程,栈区独立,并共享进程中的数据区,文本区,堆区。 阅读详情

相关推荐

探测器反向偏压_光探测器PN结原理

1 光探测原理在光的作用下,当光敏物质中的电子直接吸收光子的能量足以客服原子核的束缚时,电子就会从基态被激发到高能态,脱离原子核的束缚,在外电场作用下参与导电,因而产生了光电效应。(这里需要说明的是,如果光子不是直接与电子起作用而是能量被固体晶格振动吸收,引起固体的温度升高,导致固体电学性质的改变,这种情况就不是光电效应而是热电效应)。根据所用结的种类的不同,可分为PN结,PIN 结型,...

weixin_42489104的博客 2548

多线程(创建,终止,等待,分离),线程安全

线程概念:线程是什么? 进程与线程进行多任务处理的不同之处? 线程间的共享与独有 线程控制:等待与分离是什么?线程安全: 概念:线程安全是什么?实现:同步与互斥(概念) 互斥的实现--互斥锁:互斥锁实现互斥的原理? 死锁:概念-死锁是什么? 如何产生的?如何预防?如何避免? 同步的实现--条件变量&信号量(各自的本质是什么) 生产者与消费者模型:应用场景,优点,实现

qq_43551810的博客 173

网络攻防技术——MD5碰撞试验

一、题目 本次实验主要是加深大家对MD5碰撞及其原理的理解,使用SEED实验环境中的工具及编程语言,完成以下任务: a)使用md5collgen生成两个MD5值相同的文件,并利用bless十六进制编辑器查看输出的两个文件,描述你观察到的情况; b)参考Lab3_task2.c的代码,生成两个MD5值相同但输出不同的两个可执行文件。 c)参考Lab3_task3.c的代码,生成两个MD5值相同但代码行为不相同的可执行文件。 d)回答问题:通过上面的实验,请解释为什么可以做到不同行为的两个可执行文件具有相同的M

学习记录 3621

多线程编程-线程控制与属性(结合与分离)

进程在各自独立的地址空间中运行,进程之间共享数据需要用mmap或者进程间通信机制,而当需要在一个进程中同时执行多个控制流程并发执行多个任务时,多线程即为出现。 在linux下,一个进程中的多线程都在进程的地址空间中运行,它的控制流程可以长期并存,操作系统会在各线程之间调度和切换:特点如下 1.线程都在当前进程的地址空间中运行,如图: 创建一个进程需要创建自己的地址空间,创建页

L_XRUI的博客 1345

从MC到DC:三维重建算法的核心原理与实战对比

本文深入对比了三维重建领域两大经典算法Marching Cubes(MC)与Dual Contouring(DC)的核心原理与实战表现。MC算法原理直观、实现简单,但存在特征丢失和二义性问题;DC算法通过求解二次误差函数(QEF)和利用法向量信息,能更好地保留模型的尖锐特征,但计算更复杂。文章结合医学影像处理实例,为开发者根据速度、精度和特征保真度需求选择合适算法提供了清晰指南。

weixin_29251131的博客 1034

3. ChaosBlade-Box平台安装

参考自:https://chaosblade.io/docs/about-chaosblade/box-introduce/通过ChaosBlade-Box可实现chaosblade等已托管工具自动化部署,按照社区的建立的混沌实验模型统一实验场景,根据主机、Kubernetes、应用来划分目标资源,通过目标管理器来控制,在实验创建页面,可以实现白屏化的目标资源选择。

lldhsds的专栏 2486

linux下线程的分离和结合属性

在任何一个时间点上,线程是可结合的(joinable),或者是分离的(detached)。一个可结合的线程能够被其他线程收回其资源和杀死;在被其他线程回收之前,它的存储器资源(如栈)是不释放的。相反,一个分离的线程是不能被其他线程回收或杀死的,它的存储器资源在它终止时由系统自动释放。 默认情况下,线程被创建成可结合的。为了避免存储器泄漏,每个可结合线程都应该要么被显示地回收,即调用p...

diyudong4681的博客 169

STM32 RTC_WaitForSynchro()死循环问题分析与LSI时钟优化实践

本文深入分析了STM32使用LSI时钟源时,调用RTC_WaitForSynchro()函数陷入死循环的根本原因。问题核心在于RTC时钟域未正确使能,导致硬件同步标志RSF无法置位。文章提供了通过显式调用RCC_RTCCLKCmd(ENABLE)函数启用RTC时钟总开关的解决方案,并分享了编写健壮RTC/BKP初始化代码、增加超时机制等最佳实践,确保系统稳定运行。

weixin_29185493的博客 511

线程的分离属性

在任何一个时间点上,线程是可结合的(joinable)或者是分离的(detached)。 可结合属性:创建线程时,线程的默认属性是可结合的, 如果一个可结合线程结束运行但没有被join,则它的状态类似于进程中的Zombie(僵死),即它的存储器资源(例如栈)是不释放的,所以创建线程者应该调用pthread_join来等待线程运⾏结束,并得到线程的退出码,回收其资源。 可分离属性:通过

Better_JH的博客 3763

ElasticSearch集群搭建

docker安装es集群

weixin_46562226的博客 2026

避坑指南:从聚宽迁移到QMT必须知道的5个细节(含Redis连接异常处理)

本文详细解析了从聚宽迁移到QMT平台时需注意的5个关键细节,特别是Redis连接池优化和xtquant重连机制。通过实战代码示例,帮助量化团队解决信号传递稳定性、时间同步、滑点控制等核心问题,确保交易策略平稳过渡。

weixin_27303545的博客 430

【Linux篇章】线程操控术2:如何让代码如千军万马听你号令(精讲线程控制)

 本篇文章承接上篇关于线程概念;在此篇中;会讲到线程相关使用;比如创建,终止;等待;分离等相关函数接口;以及linux的线程底层是怎么实现的;那些接口函数是怎么封装的;线程id和轻量级进程之间关系;地址空间分布等等再到最后自己模拟实现简单版的线程封装;故本篇文章主要带大家了解linux线程如何使用;底层又是怎么样的;从而对线程有更加清晰地认识。

羑悻的博客. 3246

数字逻辑Fundamentals of Digital Logic with Verilog Design | 3rd Edition Solutins Chapter 3(step by step)

第三章3-1~3-27全部习题解析和代码模块

weixin_62651190的博客 1946

线程属性以及线程控制(互斥与同步)

功能:将已经定义好的互斥锁初始化。参数:mutex 要初始化的互斥锁atrr 初始化的值,一般是NULL表示默认锁返回值:成功 0失败 非零信号量的类型 信号量的变量。

m0_70493759的博客 971

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

多线程(线程控制 封装线程 线程互斥 线程同步 生产消费模型 信号量)

文章目录一.背景知识再谈地址空间二.线程pthread_create为什么线程的调度成本更低?线程的优点线程的缺点线程与进程的区别共享每个线程独一份三.线程控制线程的创建与等待等待线程pthread_join线程创建的传参arg线程创建的返回值与等待线程的参数retval创建多个线程新线程如何终止线程的分离四.浅谈C++11下的线程五.再谈tid线程的局部存储六.封装线程七.线程互斥认识锁与接口RAII风格锁原理角度理解锁锁是如何实现上锁解锁八.线程同步条件变量&&接口认识条件变量使用接口生

2302_78639896的博客 880

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

【Linux】线程(二:线程控制)

线程控制

2301_78636079的博客 772

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

Linux从0到1——初识线程【什么是线程/线程控制/详解tid】

1. 线程概念课本上的概念:线程是比进程更加轻量化的一种执行流;线程是在进程内部执行的一种执行流。我们的理解:线程是CPU调度的基本单位;进程是承担系统资源的基本实体。2. 理解线程每创建一个进程,就需要创建对应的地址空间mm_struct,PCB,页表。开销实际上是比较大的。那么可不可以设计一种更轻量级的进程?让这种轻量级进程,和主进程共用一个地址空间,共用一个页表?

weixin_73870552的博客 1280

线程进阶实战:资源划分与线程控制核心指南

本文深入探讨多线程编程中的资源划分与线程控制两大核心问题。首先分析了线程与进程的资源共享机制,包括线程共享的进程资源和私有资源,解释了线程崩溃导致进程退出的原因。接着详细介绍了POSIX线程库(pthread)的使用方法,涵盖线程创建、终止(三种方式)、等待与分离等关键操作。文章通过大量代码示例演示了多线程任务构建、线程同步与资源回收等实战技巧,强调合理资源划分和精准线程控制对提升程序性能、稳定性的重要性。最后总结指出,优秀的线程设计需要平衡并发优势与系统稳定性,实现资源合理分配和线程高效协作。

心向往之,行必能至 2137

线程的基本概念

线程的概念: 1、在一个程序里的一个执行路线就叫做线程。更准确的定义为:线程是“一个进程内部的控制序列”。 2、一切进程至少都有一个执行线程。 进程和线程的区别: 1、进程是资源竞争的基本单位。 2、线程是程序执行的最小单位。 3、线程共享进程数据,但也拥有自己的一部分数据。 线程的优点: 1、创建一个新线程的代价要比创建一个新进程的...

yummy_alice的博客 285

Linux线程thread详解(线程池)

多线程就可以让我们的代码并行运行起来,本篇从线程的基本概念开始介绍,然后比较了多线程与多进程之间的区别。接着介绍了在 Linux 系统下的线程控制,介绍了在 Linux 系统下使用多线程的函数接口。然后讲解了线程的互斥,需要使用锁互斥,同时揭示了互斥的缺点,然后引入了线程同步,需要使用条件变量来解决。在介绍完条件变量之后,我们又介绍了在多线程中常用的生产消费模型,实现了两种经典的生产消费模型:阻塞队列(使用条件变量和互斥锁完成)和环形队列(使用信号量和互斥锁完成)。同时还介绍了线程安全和可重入以及死锁的概念

m0_74830524的博客 1329

linux 线程分离,Linux下线程的控制与分离

一、线程的概念:线程是运行在进程地址空间的,是进程的执行分流。它是执行进程内部的一个代码片段为了让进程更好的完成。也可以说,进程是承担系统资源的实体,而线程进程运行调度的基本单位。由于同一进程的多个线程共享同一地址空间,因此Text Segment、Data Segment都是共享的,如果定义一个函数,在各线程中都可以调用,如果定义一个全局变量,在各线程中都可以访问到,除此之外,各线程还共享以下进...

weixin_29574211的博客 570

【Linux】线程概念及线程控制

1、进程与线程 什么是线程? 在一个程序里的一个执行路线就叫做线程,即线程是“一个进程内部的控制序列” 一切进程至少都有一个执行线程 线程在进程内部运行,本质是在进程地址空间内运行 在Linux系统中,在cpu眼中,看到的pcb都要比传统的进程更加轻量化 线程是一个执行流,用来运行代码,处理数据。 线程概念: 先说进程:在传统操作系统中使用pcb来描述一个程序的运行---pcb就是进...

swag_wg的博客 225

[总结]Linux下的线程控制

一、线程概念   我个人理解线程,说简单点,是程序的一个控制流程,从代码的角度来看,它控制着一个函数的执行;   说复杂点,在linux下,它就是一个进程(仅限linux),因为在linux下对于线程并没有特别的数据结构去描述它.   简而言之,线程是代码的一个执行流. 二、线程与进程的区别   线程与进程的区别,足够再写一篇博客了,在这里,我总结一下(夹杂着多线程与多进程的区...

139

Linux-线程(一)创建 终止 等待线程

注意:在Linux上线程函数位于libpthread共享库中,因此在编译时要加上-lpthread选项。 1.线程概念 1)线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。另外,线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,

Nou_Camp的博客 591

线程概念与控制 [ 中 ]

本文深入探讨了Linux系统中的线程概念与控制机制。文章首先分析了线程相比进程的优势:创建开销小、切换开销低、资源占用少、多核并行能力强以及I/O操作重叠能力。同时指出线程并非越多越好,需根据计算密集型和I/O密集型场景合理设置线程数。文章详细讲解了线程的缺点,包括性能损失、健壮性降低、访问控制不足和编程调试复杂度增加。通过代码示例演示了POSIX线程库的使用,包括线程创建、等待、终止和分离等操作,并分析了线程ID、参数传递和返回值处理的机制。最后通过多线程示例揭示了共享资源访问的数据竞争问题,提出了堆空间

Small_entreprene的博客 1383
上一篇: 【数据结构】--------二叉树的基本知识点总结
下一篇: 【数据结构】-------二叉树的四种遍历方法(递归实现)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值