【Linux】基础:线程的概念

2023-11-14

【Linux】基础:线程的概念

摘要:本文介绍Linux下的线程概念,首先将会线程在系列教材中的定义进行抛出,从常规的操作系统进行理解线程的概念,在具体说明Linux下的进线程的管理与组织方式,以及由于该组织方式的差异,导致的接口和资源的特殊关系。并通过实验进行简单的验证。


一、概述

在以往学习过程中,一般常见对于线程的概念为:在进程内部运行的一个执行分支(执行流),是属于进程的一部分,粒度要比进程更加细化和轻量化

对于常见的操作系统,例如Windows操作系统,一个进程可能会存在多个线程,而操作系统就需要对这些线程进行管理,管理的方式与进程类似,通过相应的进程控制块来记录线程相关的属性,一般称为TCB即线程控制块。可是对于Linux有着其他的线程组织方式。

对于Linux来说,并没有线程TCB的概念,而是通过把线程称组织为“轻量级线程”,同样使用结构体PCB进程控制块,使用PCB来模拟线程。在Linux中,只创建task_struct,共享同一个地址空间,将当前进程的资源(代码和数据),划分成若干份,提供每个PCB使用

此时中央处理器CPU认知的PCB并不是过去所学习的进程的PCB,而是“轻量级进程”的PCB,一个PCB就是对应了一个需要被调度的执行流 。为此不用维护复杂的进程和线程的关系,不用单独的为线程设计任何算法和数据结构,直接使用进程的一套方法即可。只需要聚焦在线程间的资源分配上可以完成对线程的管理与组织。

其组织示意图如下(红框表示进程):

二、进程与线程

在Linux中对于进程的理解需要做出改变,对于过去进程的理解,是只有一个执行流的,可引入了线程的概念后,进程的内部可以具有多个执行流。

对于进程来说,创建的成本是非常高的,是需要较多的时间和空间的的,而且创建过程中要使用的资源非常多。但是对于线程的创建,只需要创建相应的PCB,并建立与进程地址空间的对应以及完成进程资源的分配。线程也是CPU调度的基本单位,承担进程资源的一部分基本实体,进程划分空间给线程。

线程与进程比较概述:

  • 调度:进程是拥有资源和独立调度(传统操作系统)的基本单位,调度开销大;线程是独立调度的基本单位,开销小。

  • 并发性:相互间可以并发,提高并发性,提高系统资源的利用率和系统的吞吐量;

  • 拥有资源:进程系统中拥有资源的基本单位,而线程不拥有系统资源,但线程隶属于进程的资源。体现:同一进程的所有线程都有相同的地址空间。

  • 独立性:每个进程都拥有独立的地址空间和资源,除了共享全局变量,其他进程不可以访问。而一进程的线程对其他进程不可见,对同一进程的不同线程则是共享进程的地址空间和资源;

  • 系统开销:创建、切换、通信线程的开销都比进程小;

  • 支持多处理机系统:传统单线程进程,不管有多少处理机,进程只能运行一个处理机;而多线程进程,可以多个线程分配多个处理机上执行;

三、接口关系

对于Linux来说,由于是使用了进程进行模拟,所以Linux下不会提供直接的操作线程的接口,所提供的是统同一空间内创建PCB的方法,分配资源给制定的PCB的接口。但是这种方式对于用户来说,是非常不友好的。为此,需要系统级别的工程师,在用户层对Linux轻量级进程进行接口封装,打包成库,让用户直接通过库调用接口。相关接口包括线程创建、线程等待、线程分离等,将在后续文章进行介绍。

由于使用了外部库,因此在进行接口调用时,需要对头文件和编译添加相应的内容。

四、资源关系

所有轻量级进程是在进程地址空间内部运行的,在进程地址空间中标识了大部分资源。对于各线程来说,大部分进程资源是共享的,对于在使用同一块地址空间而言,Text Segment、Data Segment都是共享的,对于函数和全局变量等在进程地址空间的数据也可以调用,除此之外,各线程还共享以下进程资源和环境:

  • 文件描述符表
  • 每种信号的处理方式(SIG_ IGN、SIG_ DFL或者自定义的信号处理函数)
  • 当前工作目录
  • 用户id和组id

可是也有会部分是私有资源,比如:栈、PCB和上下文,具体如下:

  • 线程ID
  • 一组寄存器
  • errno
  • 信号屏蔽字
  • 调度优先级

五、简单验证

在此使用接口pthread_create()创建线程,具体创建过程将会在其他文章中介绍,并通过shellps -aL命令,查看进程与线程的数量。可以发现进程是只有一个的,而对于线程,Linux将其称为light weight process)LWP,是有多个的,代码如下:

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
void* thread_run(void* args){
    const char *name = (const char*)args;
    while(1){
        printf("%s: pid---->%d\n",name,getpid());
        sleep(1);
    }
}

int main(){
    pthread_t tid;
    pthread_create(&tid,NULL,thread_run,(void*)"No.1 thread");
    while(1){
        printf("Main thread: pid---> %d\n",getpid());
        sleep(1);
    }
}
[root@VM-12-7-centos Blog_pthread]# ps -aL
    PID     LWP TTY          TIME CMD
 135308  135308 pts/3    00:00:00 test_pthread
 135308  135309 pts/3    00:00:00 test_pthread

六、其他

线程的优点

  • 创建一个新线程的代价要比创建一个新进程小得多
  • 与进程之间的切换相比,线程之间的切换需要操作系统做的工作要少很多
  • 线程占用的资源要比进程少很多
  • 能充分利用多处理器的可并行数量
  • 在等待慢速I/O操作结束的同时,程序可执行其他的计算任务
  • 计算密集型应用,为了能在多处理器系统上运行,将计算分解到多个线程中实现
  • I/O密集型应用,为了提高性能,将I/O操作重叠。线程可以同时等待不同的I/O操作。

线程的缺点

  • 性能损失:一个很少被外部事件阻塞的计算密集型线程往往无法与共它线程共享同一个处理器。如果计算密集型,线程的数量比可用的处理器多,那么可能会有较大的性能损失,这里的性能损失指的是增加了额外的同步和调度开销,而可用的资源不变。

  • 健壮性降低:编写多线程需要更全面更深入的考虑,在一个多线程程序里,因时间分配上的细微偏差或者因共享了不该共享的变量而造成不良影响的可能性是很大的,换句话说线程之间是缺乏保护的。

  • 缺乏访问控制:进程是访问控制的基本粒度,在一个线程中调用某些OS函数会对整个进程造成影响。

  • 编程难度提高:编写与调试一个多线程程序比单线程程序困难得多

线程异常

  • 单个线程如果出现除零,野指针问题导致线程崩溃,进程也会随着崩溃
  • 线程是进程的执行分支,线程出异常,就类似进程出异常,进而触发信号机制,终止进程,进程终止,该进程内的所有线程也就随即退出

线程用途

  • 合理的使用多线程,能提高CPU密集型程序的执行效率
  • 合理的使用多线程,能提高IO密集型程序的用户体验(如生活中我们一边写代码一边下载开发工具,就是多线程运行的一种表现)

补充:

  1. 代码将会放到:Linux_Review: Linux博客与代码 (gitee.com) ,欢迎查看!
  2. 欢迎各位点赞、评论、收藏与关注,大家的支持是我更新的动力,我会继续不断地分享更多的知识!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Linux】基础:线程的概念 的相关文章

  • Linux 中 m 标志和 o 标志将存储在哪里

    我想知道最近收到的路由器通告的 m 标志和 o 标志的值 从内核源代码中我知道存储了 m 标志和 o 标志 Remember the managed otherconf flags from most recently received R
  • SSH,运行进程然后忽略输出

    我有一个命令可以使用 SSH 并在 SSH 后运行脚本 该脚本运行一个二进制文件 脚本完成后 我可以输入任意键 本地终端将恢复到正常状态 但是 由于该进程仍在我通过 SSH 连接的计算机中运行 因此任何时候它都会登录到stdout我在本地终
  • 为什么 Linux 没有 DirectX API?

    在考虑现代显卡的 Windows 系统上 DirectX API 的驱动程序端实现时 我想知道为什么此实现在非 Windows 系统 尤其是 Linux 上不可用 由于明显缺乏此功能 我只能假设有一个我无视的充分理由 但在我的原始理解中 我
  • python获取上传/下载速度

    我想在我的计算机上监控上传和下载速度 一个名为 conky 的程序已经在 conky conf 中执行了以下操作 Connection quality alignr wireless link qual perc wlan0 downspe
  • 如何使用 Cloud Init 挂载未格式化的 EBS 卷

    Context 我正在使用https wiki jenkins io display JENKINS Amazon EC2 Plugin https wiki jenkins io display JENKINS Amazon EC2 Pl
  • tcpdump 是否受 iptables 过滤影响?

    如果我的开发机器有iptables规则到FORWARD一些数据包 这些数据包是否被 tcpdump 捕获 我有这个问题 因为我知道存在其他链称为INPUT如果数据包路由到 它会过滤发往应用程序的数据包FORWARD链 它会到达吗tcpdum
  • linux-x64 二进制文件无法在 linuxmusl-x64 平台上使用错误

    我正在安装Sharp用于使用 package json 的 Nodejs 项目的 docker 映像上的映像压缩包 当我创建容器时 我收到有关 Sharp 包的以下错误 app node modules sharp lib libvips
  • 从 ttyUSB0 写入和读取,无法得到响应

    我对 Linux tty 不太有经验 我的环境是带有丰富 USB 串行的 Raspbian 什么有效 stty F dev ttyUSB0 38400 cu l dev ttyUSB0 s 38400 cu to dev ttyUSB0作品
  • 尽管 if 语句,Visual Studio 仍尝试包含 Linux 标头

    我正在尝试创建一个强大的头文件 无需更改即可在 Windows 和 Linux 上进行编译 为此 我的包含内容中有一个 if 语句 如下所示 if defined WINDOWS include
  • CMake 链接 glfw3 lib 错误

    我正在使用 CLion 并且正在使用 glfw3 库编写一个程序 http www glfw org docs latest http www glfw org docs latest 我安装并正确执行了库中的所有操作 我有 a 和 h 文
  • 使用包管理器时如何管理 Perl 模块?

    A 最近的问题 https stackoverflow com questions 397817 unable to find perl modules in intrepid ibex ubuntu这让我开始思考 在我尝试过的大多数 Li
  • .net-core:ILDASM / ILASM 的等效项

    net core 是否有相当于 ILDASM ILASM 的功能 具体来说 我正在寻找在 Linux 上运行的东西 因此为什么是 net core ildasm 和 ilasm 工具都是使用此存储库中的 CoreCLR 构建的 https
  • 与 pthread 的进程间互斥

    我想使用一个互斥体 它将用于同步对两个不同进程共享的内存中驻留的某些变量的访问 我怎样才能做到这一点 执行该操作的代码示例将非常感激 以下示例演示了 Pthread 进程间互斥体的创建 使用和销毁 将示例推广到多个进程作为读者的练习 inc
  • Intel 上的 gcc 中的 _mm_pause 用法

    我参考过这个网页 https software intel com en us articles benefitting power and performance sleep loops https software intel com
  • 为什么opencv videowriter这么慢?

    你好 stackoverflow 社区 我有一个棘手的问题 我需要你的帮助来了解这里发生了什么 我的程序从视频采集卡 Blackmagic 捕获帧 到目前为止 它工作得很好 同时我用 opencv cv imshow 显示捕获的图像 它也工
  • 错误:“rjags”的包或命名空间加载失败

    在终端的 conda 环境之一中 我能够成功安装包 rjags 但是 当我在该环境中运行 R 并运行库 rjags 时 出现以下错误 加载所需的包 coda 错误 rjags 的包或命名空间加载失败 rjags 的 loadNamespac
  • 如何使用Android获取Linux内核的版本?

    如何在 Android 应用程序中获取 Linux 内核的版本 不是 100 确定 但我认为调用 uname r 需要 root 访问权限 无论如何 有一种不太肮脏的方法可以做到这一点 那就是 System getProperty os v
  • Apache 访问 Linux 中的 NTFS 链接文件夹

    在 Debian jessie 中使用 Apache2 PHP 当我想在 Apache 的文档文件夹 var www 中创建一个新的小节时 我只需创建一个指向我的 php 文件所在的外部文件夹的链接 然后只需更改该文件夹的所有者和权限文件夹
  • 使用os.execlp时,为什么`python`需要`python`作为argv[0]

    代码是这样的 os execlp python python child py other args this works os execlp python child py other args this doesn t work 我读过
  • ansible unarchive 模块如何查找 tar 二进制文件?

    我正在尝试执行一个 ansible 剧本 该剧本的任务是利用unarchive模块 因为我是在 OSX 上执行此操作 所以我需要使用它gnu tar 而不是bsd tar通常与 OSX 一起提供 因为BSD tar 不受官方支持 https

随机推荐

  • 《C语言运算符100例》优先级面试错题

    建议先阅读基础教学 十万字C语言动漫教程 一 前言 运算符优先级一直是让人头疼的东西 趁着 字节取消大小周 的势头来临 通宵整理了一个思维导图出来 希望对你有所帮助 这篇文章 我会仔细分析这张思维导图 所有的 C语言运算符的用法都在这里了
  • minikube踩坑记

    minikube如何使用本地镜像 需要执行 eval minikube docker env 然后再重新打镜像 并运行即可 docker build t foo 0 0 1 kubectl run hello foo image foo 0
  • Android Things——SPI通信

    1 SPI 1 1 概念 SPI是串行外设接口 Serial Peripheral Interface 的缩写 SPI 是一种高速的 全双工 同步的通信总线 并且在芯片的管脚上只占用四根线 节约了芯片的管脚 同时为PCB的布局上节省空间 提
  • 顺序存储结构的插入与删除

    1 获得元素的操作 要获得线性表中第i个元素的值 只要i的数值在数组下标范围内 就把i 1下标的值返回即可 define OK 1 define ERROR 0 define FALSE 0 define TRUE 1 typedef in
  • 线性方程组的直接解法c语言,2 线性方程组的直接解法

    2 1 例题解答 例 2 1 用Gauss消元法解方程组 解 直接建立求解该方程组的M文件Gauss m如下 求解例题2 1 高斯法求解线性方程组Ax b A为输入矩阵系数 b为方程组右端系数 方程组的解保存在x变量中 先输入方程系数 A
  • GPIO / LED驱动编程开发

    GPIO LED 驱动开发编程 一般来说 GPIO的Pin都是可选功能的 GPIO x selects the function of GPIO Pin 为什么 不要问 操作 1 将某一个GPIO选择功能复用为GPIO 2 将该GPIO选择
  • MIT6.00 1x Lecture 1 - Introduction to Computation 学习笔记

    l MIT6 00 1x 麻省理工 计算机科学和Python编程导论 Lecture 1 Introduction to Computation 计算科学简介 1 1 Basics of computation 计算科学基础 Goal 本课
  • opencv形状目标检测

    1 圆形检测 OpenCV图像处理中 找圆技术 的使用 图像处理 双翌视觉OpenCV图像处理中 找圆技术 的使用 图像处理 双翌视觉https www shuangyi tech com news 224 htmlopencv 找圆心得
  • .h5文件的写入和读取(HDF5)

    先理解 h5文件的数据组织方式 h5文件中有两个核心的概念 组 group 和数据集 dataset 一个h5文件就是 dataset 和 group 二合一的容器 dataset 简单来讲类似数组组织形式的数据集合 像 numpy 数组一
  • python数据结构课堂笔记5:排序与查找

    排序与查找 文章目录 排序与查找 查找算法 顺序查找 算法分析 二分查找 算法分析 排序算法 冒泡排序和选择排序算法 冒泡排序Bubble Sort
  • C/C++内存泄漏及检测

    本文参考内存泄漏检测 该死系统存在内存泄漏问题 项目中由于各方面因素 总会有人抱怨存在内存泄漏 系统长时间运行之后 可用内存越来越少 甚至导致了某些服务失败 内存泄漏是最难发现的常见错误之一 因为除非用完内存或调用malloc失败 否则都不
  • 搭建J2EE开发平台-Eclipse+MySql+tomcat

    开完J2EE视频之后自己从网上把需要用到的东西下载了下来 分享之 首先是Eclipse开发环境 我记得在马士兵的一个教程里讲的是用lomboz Eclipse 不过那个视频讲的是06年的事了 并且lomboz官网上最新的也只有2007年出的
  • 'str' object has no attribute 'name'

    imgName E AndroidWork Bird Identification App master Bird Identification Server mask rcnn master images cars jpg 出错版 arg
  • UME - 丰富的Flutter调试工具

    背景 目前西瓜视频作者侧 Flutter 业务场景已经覆盖了 40多个页面 包括视频播放场景 用户侧核心场景包括我的 Tab 也已经是 Flutter 在开发过程中 暴露了一些问题 debug 调试难 离开了 IDE 后犹如抓瞎 PM 设计
  • 十六、K8s安全管理与资源限制

    实验环境 按照图示部署好了K8s集群 一个Master 两个worker nodes 访问控制概述 apiserver作为k8s集群系统的网关 是访问及管理资源对象的唯一入口 余下所有需要访问集群资源的组件 包括kube controlle
  • C语言【求最大公约数、最小公倍数】详解

    题目 从键盘输入两个数字 并求出他们的最大公约数 解题思路 一 当我们看到题目时 首先思考求什么是最大公约数 什么 是最小公倍数 最大公约数 指两个或两个以上共有的约数中最大的那个 最小公倍数 指两个或两个以上共有的倍数中最小的那个 接下来
  • Firewalld防火墙转换成Iptables

    关闭及停止使用 firewalld systemctl mask firewalld systemctl stop firewalld 安装iptables yum install y iptables services 生效及iptabl
  • Java海龟画图turtle多彩螺旋线

    利用turtle画多彩螺旋线 思路 在画正多边形的基础上 步长不是一直相同 而是越来越长 并且角度比画正多边形需要的角度多一些 每次拐弯变换颜色 Size是螺旋的大小 Step的每一步的长度 每走一步拐弯一次 Densi是密度 角度越小 螺
  • 【C++11】 列表初始化 auto 范围for 新增关键字 新增容器

    文章目录 1 列表初始化 2 auto 范围for 3 新增关键字 3 1 decltype 3 2 default 3 3 delete 3 4 final与override 4 总结 1 列表初始化 由c语言的规则我们知道 一般只有数组
  • 【Linux】基础:线程的概念

    Linux 基础 线程的概念 摘要 本文介绍Linux下的线程概念 首先将会线程在系列教材中的定义进行抛出 从常规的操作系统进行理解线程的概念 在具体说明Linux下的进线程的管理与组织方式 以及由于该组织方式的差异 导致的接口和资源的特殊