Linux--多线程

news2024/11/15 11:26:00

目录

    • 1. 什么是线程
    • 2. 创建线程
    • 3. 线程等待
      • 3.1 pthread_join函数
      • 3.2 线程分离
      • 3.2 线程终止的方案
    • 4. 线程ID

1. 什么是线程

Linux中没有专门为线程设计TCB,而是用进程的PCB来模拟进程。 这也是为什么有种观点会说Linux下没有真正意义上的线程。

对于线程来说,只创建task_struct,共享同一个地址空间,当前进程的资源(代码+数据),划分为若干份,让每个PCB使用。

线程可以认为是进程里的一个执行流(每一个PCB),由于线程的创建并不需要像进程那样创建数据结构、地址空间等,而是复用进程的PCB等资源,所以线程也被看作是进程的一部分。

有两个要点:

  1. 线程在进程的地址空间内运行
  2. CPU调度的时候,只看PCB,每一个PCB已经被分配指向的数据和方法,CPU可以直接调度

在这里插入图片描述

这样的设计有一个很大的优点:不用维护复杂的进程和线程的关系,不用单独为线程设计任何算法,直接使用进程的一套相关的方法。OS只需要聚焦在线程间的资源分配上就行了。

所以很明显,创建进程的成本比创建线程大的多。

在windows系统中,采用的是和进程类似的方法,也就是线程自己重新创建一份TCB等结构,可以知道其源码肯定非常复杂。

2. 创建线程

线程创建函数:pthread_create

在这里插入图片描述

参数:
thread:返回线程ID
attr:设置线程的属性,attr为NULL表示使用默认属性
start_routine:是个函数地址,线程启动后要执行的函数
arg:传给线程启动函数的参数

返回值:成功返回0;失败返回错误码

编写一个函数来验证它们是否处于同一个进程(由于使用的是第三方库,编译时需要-lpthread链接):

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

void* thread_run(void* args)
{
    const char* id = (const char*)args;
    while(1){
      printf("我是%s线程:%d\n",id,getpid());
      sleep(1);
    }
}
int main()
{
    pthread_t tid;
    pthread_create(&tid,NULL,thread_run,(void*)"thread 1");
    while(1){
      printf("我是main线程:%d\n",getpid());
      sleep(1);
    }
    return 0;
}

运行结果:

在这里插入图片描述

首先,两个死循环都能跑起来,如果仅仅只有一个线程,这是根本不可能实现的,说明此时创建了新的线程

其次,可以看见他们的pid都是一样的,说明它们是同一个进程

最后,当收到二号信号的时候,两个线程都直接退出,说明确实是只有一个进程,并且两个线程是同一个进程。

ps -aL是查看线程资源的指令:

在这里插入图片描述

这里的LWP其实就是线程的标识符,相当于进程的PID。6548其实就是此时的主线程,6549就是另一个线程。

操作系统调度线程的时候,看的其实是LWP,而不是PID。

也可以批量创建线程:

void* thread_run(void* args)
{}
int main()
{
    pthread_t tid[5];
    for(int i = 0;i < 5;i++){
       pthread_create(tid+i,NULL,thread_run,(void*)"thread 1");
    }
    return 0;
}

运行结果:

在这里插入图片描述

可以看见LWP刚好有六个属于test程序的线程,第一个LWP=PID的是主线程,其他的五个都是按照顺序生成的子线程。

线程健壮性不强,在一个进程下的线程,如果有一个崩溃了,其他的也会随之崩溃。

3. 线程等待

3.1 pthread_join函数

和进程一样,线程也是需要等待的,否则就会造成类似于“僵尸进程”的问题。

线程等待函数pthread_join:

在这里插入图片描述

参数:

thread表示需要等待的线程id;

retval是一个输出型参数,用来获取新线程退出的时候,函数的返回值。由于新线程创建的时候函数返回值是void*,所以要将该返回值输出,就要用二级指针void**。

返回值:成功返回0,失败返回错误码。

下列程序可以显示出,主线程确实是可以等待其他线程,并拿到其返回值:

void* thread_run(void* args)
{
    const char* id = (const char*)args;
    while(1){
      printf("我是%s线程:%d\n",id,getpid());
      sleep(1);
      break;
    }
    return (void*)11;//随意设置返回值
}
int main()
{
    pthread_t tid;
    pthread_create(&tid,NULL,thread_run,(void*)"thread 1");
    等待
    void* status = NULL;
    pthread_join(tid,&status);
    printf("返回值:%d\n",(int)status);
    return 0;
}

运行结果:

在这里插入图片描述

可以看到status中确实保存了该新线程的返回值。

值得注意的是,当线程异常的时候,该函数并不会进行处理,因为线程异常已经是属于进程层面的问题了。

3.2 线程分离

如果一个线程不需要被等待,可以将其分离:

在这里插入图片描述

分离后的线程不能被等待,主线程v不退出,新线程运行完毕之后会自动释放资源。

3.2 线程终止的方案

  1. return:main函数中return代表主线程退出,在其他线程中return代表当前线程退出。

  2. 新线程通过pthread_exit终止自己,但是不能用exit,因为那是用来终止进程的,除非你想直接终止该进程。

在这里插入图片描述
参数是退出码,强转成void*。

  1. 取消目标线程,直接通过线程id取消线程

在这里插入图片描述

4. 线程ID

我们所打印的线程ID其实是pthread库在地址空间当中映射之后的地址,该地址能快速地找到对应线程的相关属性,该地址与LWP是一一对应的关系。

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

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

相关文章

Elasticsearch搜索引擎(二)——SpringData Elasticsearch

SpringData Elasticsearch SpringData介绍 Spring Data是一个用于简化数据库访问&#xff0c;并支持云服务的开源框架。其主要目标是使得对数据的访问变得方便快捷&#xff0c;并支持map-reduce框架和云计算数据服务。 Spring Data可以极大的简化JPA的写法&#xff0c;可以在…

CSND近期推出的猿如意到底怎么样?

CSND近期推出的猿如意到底怎么样&#xff1f; 投稿测评正文 猿如意传送门 猿如意下载地址&#xff1a;猿如意-程序员的如意兵器,工具代码,一搜就有 猿如意使用了几次了&#xff0c;今天来想分享一下我对于猿如意的使用感受吧&#xff01;&#xff01; 先说结论&#xff1a…

吴恩达《机器学习》——Logistics回归代码实现

Logisitc回归1. Sigmoid与二分类Sigmoid函数为什么Sigmoid函数可以表示二分类概率&#xff1f;2. Logistics回归交叉熵损失函数梯度过拟合与欠拟合正则化3. Python代码实现4. 单维与多维Logistic分类单维数据分类多维数据分类数据集、源文件可以在Github项目中获得 链接: https…

04 kafka 中一些常用的配置的使用

前言 呵呵 也是最近有一些 搭建 kafka 的环境的需求 然后 从新看了一下 一部分的配置情况, 这里 大致理一下 一些我这里比较关心的配置 那些配置关联了 kafka 服务器绑定服务 绑定 tcp 服务的配置来自于这里, 读取的是 config.dataPlaneListeners config.dataPlaneListen…

Java母婴商城母婴店孕妇商城婴幼儿商城网站系统源码

简介 java使用ssm开发的母婴商城系统&#xff0c;用户可以注册浏览商品&#xff0c;加入购物车或者直接下单购买&#xff0c;在个人中心管理收货地址和订单&#xff0c;管理员也就是商家登录后台可以发布商品&#xff0c;上下架商品&#xff0c;处理待发货订单等。 演示视频&…

Allegro如何在PCB上查看pin number的三种方法操作指导

Allegro如何在PCB上查看pin number的三种方法操作指导 Allegro支持快捷的在PCB上查看pin number,如下图 具体操作如下 方法一:show element 选择Show Element命令Find选择Pins

2022年学习机器人和人工智能的一些期待

2022年学习机器人和人工智能的一些体会 2023年即将到来&#xff0c;满满的期待。 做好规划是非常非常重要的&#xff0c;有时候甚至比认真做事本身更为重要。 《礼记中庸》&#xff1a;“凡事豫则立&#xff0c;不豫则废。言前定则不跲&#xff0c;事前定则不困&#xff0c;行…

视频解码学习备忘

媒体文件知识 日常都是播放器直接播&#xff0c;其实这里面还有不少内容的。 首先是视频容器&#xff0c;就是所谓的.mp4 .mkv 这类文件,其目的主要就是用来存放音频视频字幕等内容&#xff0c;所以叫做容器。这些都有一定规范&#xff0c;比如mp4&#xff0c;叫ISO 14496-12…

流程图+BPMN+脑图 JointJS++ 3.6.3 Crack

一个库&#xff0c;‍ 无限的UI选择&#xff0c;直接在您的应用程序中享受交互式流程图、BPMN 和其他图表工作室。利用我们的模板化应用程序&#xff0c;将开发时间缩短至几天。 经过十多年和数百万行代码的编写&#xff0c;我们推出了一组随时可用的功能&#xff0c;以帮助您创…

数据结构进阶 二叉树OJ题二

作者&#xff1a;小萌新 专栏&#xff1a;数据结构进阶 作者简介&#xff1a;大二学生 希望能和大家一起进步&#xff01; 本篇博客简介&#xff1a;介绍几道二叉树的oj题 题目一 二叉搜索树与双向链表 输入一棵二叉搜索树&#xff0c;将该二叉搜索树转换成一个排序的双向链表…

帆软—图表专题

饼图 优点&#xff1a;能很直观的看到每一个部分在整体中所占的比例。 缺点&#xff1a;不适合较大的数据集&#xff08;分类&#xff09;展现&#xff0c;数据项中不能有负值&#xff0c;当比例接近时&#xff0c;人眼很难准确判别。 变形饼图 柱形图 特点 优点&#xff…

SpringBoot HandlerMethodArgumentResolver接口自定义参数解析器

参考资料 【SpringBoot】HandlerMethodArgumentResolver的简单使用HandlerMethodArgumentResolver(参数解析器)的作用使用小案例HandlerMethodArgumentResolver用于统一获取当前登录用户 目录一. 需求二. 前期准备三. 实现HandlerMethodArgumentResolver接口四. 将自定义的方法…

一套javassf门户网站管理系统源码分享

淘源码&#xff1a;国内专业的免费源码下载平台 JAVA SSF项目框架源码 后台管理系统源码 一套以SpringMVCSpringHibernateFreemarkerShiroLuceneHtml5jQuery为技术核心架构的门户网站管理系统源码。 源码免费分享&#xff0c;需要源码学习可私信我。 主要功能&#xff1a; 内…

笑对过往、活在当下、期盼未来

哈喽大家好&#xff0c;我是阿Q。 去年今日&#xff0c;也是安静的午后&#xff0c;拿起铅笔在纸上寥寥草草的写下几个年终关键词&#xff0c;思索良久&#xff0c;迟迟未能下笔。 时至今日&#xff0c;年末将至&#xff0c;再次执笔已时隔一年&#xff0c;再不拿笔记录这转瞬…

Python制作粒子烟花,程序员的跨年姿势

跨年倒计时还有半天&#xff1f;我已经开始整烟花了&#xff0c;虽然不是很好看吧&#xff0c;但是也能将就看看 &#x1f625; 这个的背景图&#xff0c;音乐&#xff0c;还有文字都是可以自己修改的哦 效果展示 依次导入本次需要使用到的模块 import random import pygame…

免费的JPEG 恢复软件 - 照片删除了怎么恢复?

照片删除了怎么恢复? 照片在我们的生活中起着至关重要的作用&#xff0c;因为它们可以承载我们的快乐回忆&#xff0c;记录我们的日常生活&#xff0c;分享我们的快乐等。我们将在智能手机、相机或计算机上拍摄并存储大量 JPEG 图片。但是&#xff0c;无论我们多么小心地保留它…

Python和MySQL对比(2):用Pandas 实现MySQL的 union 和 join 语法效果

文章目录一、前言二、语法对比数据表unionjoin1、两表 inner join2、两表 left join3、两表 right join4、两表 outer join5、多表 join三、小结一、前言 环境&#xff1a; windows11 64位 Python3.9 MySQL8 pandas1.4.2 本文主要介绍 MySQL 中的union和join如何使用pandas实现…

Spring 核心概念 IOC/DI IOC容器 Bean

目录 一&#xff1a;代码书写现状 二&#xff1a;核心思想 一&#xff1a;代码书写现状 常规操作如上,但存在着问题,将项目上线后&#xff0c;需要将数据层进行更换,更换如下&#xff1a; 数据层更换后&#xff0c;业务层也需要进行更换&#xff0c;更换如下&#xff1a; 数据…

NLP学习笔记(五) 注意力机制

大家好&#xff0c;我是半虹&#xff0c;这篇文章来讲注意力机制 (Attention Mechanism) 在序列到序列模型中的应用 在上一篇文章中&#xff0c;我们介绍了序列到序列模型&#xff0c;其工作流程可以概括为以下两个步骤 首先&#xff0c;用编码器将输入序列编码成上下文向量&a…

费控产品之易快报洞察解析

1.费控行业洞察 1.1 概念及管理范畴界定 费控业务的本质是企业支出的管理&#xff0c;因此分析费控要从企业支出管理的宏观范畴来看&#xff0c;企业支出主要包括两方面&#xff0c;一个是企业成本&#xff0c;一个是期间费用。期间费用就是我们常说的管理费用、销售费用和财务…