【Linux】线程详解之线程概念

2023-11-11

前言

在我们的教材中,对线程给出以下的概念:

是进程内部的一个执行分支,在进程的内部运行,属于进程的一部分,比进程更加轻量化。

可能有的人看完之后都是懵的,什么叫在进程的内部运行,什么又是执行分支,为什么比进程轻量化,我们就带着这三个问题,重新来探究一下线程。

一、什么是线程

经过前边的学习,我们知道进程拥有一个PCB,在Linux中被称为task_struct,并且有一个进程地址空间,也有一个页表,通过页表指向物理内存,但是从今天开始,对进程的概念可能发生变化,这个我们后边来说,在Linux中,并没有真正的线程,而是使用进程的PCB来模拟线程,也就是说一个线程在创建时,只会去创建一个PCB,而这个PCB也指向主线程的虚拟地址空间,和其他线程一起共享内存的代码和数据。一个线程也被称为一个执行流,这是因为线程是被CPU调度的执行流,而一个进程就是分配系统资源的基本实体。

以我们的实际生活来类比,我们可以将操作系统比作中国,而每一个进程就是一个家庭,而每个家庭中的成员就是一个一个线程,家庭中的户主就是一个主线程,每个家庭是互不干扰的,这也就是进程是独立的,但是家庭中的成员是亲密的,他们可以共享代码和数据,因为一个进程中的线程组是指向同一个虚拟内存的。

在这里插入图片描述
下边给出线程的一些概念:

1.在一个程序里的一个执行路线就叫做线程(thread)。更准确的定义是:线程是“一个进程内部的控制序列”

线程其实在进程的虚拟地址空间内,并且是进程的一个执行分支,所以说线程是一个进程内部的的控制序列。

2.一切进程至少都有一个执行线程

一个进程至少有一个执行线程,就像我们之前看到的进程一样,并没有创建线程,所以就只有一个线程,也就是只有一个PCB。

3.线程在进程内部运行,本质是在进程地址空间内运行

线程本质就是在进程地址空间内运行,与进程看到的是同一份地址空间。

4.在Linux系统中,在CPU眼中,看到的PCB都要比传统的进程更加轻量化

现在的进程,是创建很多的PCB,但是只有一个地址空间,进程将数据和代码分配给每一个PCB,所以一个进程中可能有多个PCB,其实使PCB更加轻量化了。

5.透过进程虚拟地址空间,可以看到进程的大部分资源,将进程资源合理分配给每个执行流,就形成了线程执行流

os不需要再给线程实现一套调度算法,而是复用进程的调度算法,os只需要将进程的代码和数据分配给每一个线程就好了,这样线程就是进程中的一个执行流。

二、线程和进程对比

进程是是承担分配系统资源的基本实体,而线程是CPU进程调度的基本单位,是承担进程资源一部分的基本实体。

每个进程都具有独立性,但是可以通过进程间通信,使进程之间产生联系,而线程几乎没有独立性,因为在进程的不同线程共享地址空间,但是线程也有自己私有的一部分数据:

PCB控制块
线程ID
一组寄存器

errno
信号屏蔽字
调度优先级

在这些里边,我们要清楚记得,线程的PCB控制块,上下文数据,栈空间是独立的。
进程的多个线程共享 同一地址空间,因此Text Segment、Data Segment都是共享的,如果定义一个函数,在各线程中都可以调用,如果定义一个全局变量,在各线程中都可以访问到,除此之外,各线程还共享以下进程资源和环境:

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

进程和线程有以下的关系:
在这里插入图片描述
可能一个进程中只有一个线程,也可能有多个线程,进程数:线程数=1:n。

三、线程的优点

创建一个新线程的代价要比创建一个新进程小得多

由于创建进程的成本是非常高的,成本分为时间和空间,一个线程只需创建一个PCB,但是创建进程必须创建页表,进程地址空间等。

=与进程之间的切换相比,线程之间的切换需要操作系统做的工作要少很多

进程之前的切换,会切换进程的PCB,地址空间,页表,上下文数据,而线程只需要切换PCB,上下文数据即可,因为进程中的线程共用着同一个地址空间,必然使用同一个页表。

线程占用的资源要比进程少很多

线程只占用进程中的一部分资源,这部分资源是由进程来分配的。

能充分利用多处理器的可并行数量

当有多个处理器时,一个进程中,每个PCB都可以被CPU调度,然后运行,此时将进程的任务分配给线程之后,每个线程只去完成自己的一部分任务即可。

在等待慢速I/O操作结束的同时,程序可执行其他的计算任务

当要进行I/O操作时,并且I/O比较慢时,可以让一个PCB等待,而其他的线程去执行其他的任务。

计算密集型应用,为了能在多处理器系统上运行,将计算分解到多个线程中实现

计算密集型,例如解压压缩包,需要进行大量的计算,将任务分配给各个线程,就会提高效率。

I/O密集型应用,为了提高性能,将I/O操作重叠。线程可以同时等待不同的I/O操作。

例如我们在线观看电视剧,电影时,有多个线程,就可以将等待I/O的时间重叠,例如在多个线程同时等待,就可以提高效率。

四、线程的缺点

性能损失

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

通常情况下,在计算密集型线程应比处理器的数量少,如果多于处理器的数量,CPU在调度线程时会过度切换,所以说线程也并不是越多越好。

健壮性降低

编写多线程需要更全面更深入的考虑,在一个多线程程序里,因时间分配上的细微偏差或者因共享了不该共享的变量而造成不良影响的可能性是很大的,换句话说线程之间是缺乏保护的。
由于多线程程序中,多个线程同时共享地址空间,所以某个线程会干扰其他线程,比如如果一个线程崩溃,进程就会崩溃,其他的线程自然而然也会崩溃。

缺乏访问控制

进程是访问控制的基本粒度,在一个线程中调用某些OS函数会对整个进程造成影响。
共享地址空间,所以可能其他线程可以访问该线程的数据。

编程难度提高

编写与调试一个多线程程序比单线程程序困难得多

五、线程异常

单个线程如果出现除零,野指针问题导致线程崩溃,进程也会随着崩溃
线程是进程的执行分支,线程出异常,就类似进程出异常,进而触发信号机制,终止进程,进程终止,该进程内的所有线程也就随即退出。
使用pthread_create接口来创建线程,详细讲解见下篇文章
在这里插入图片描述
接下来先编写一个多线程的程序:

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<pthread.h>
#define NUM 5

void* pthread_run(void* args)
{
   while(1){
     int num = *(int*)args;
        printf("我是新线程[%d], 我创建的线程ID是: %lu\n", num,pthread_self());
        sleep(2);
        if(num==3)
        {
          printf("thread number : %d quit\n", num);
          //野指针,会造成线程崩溃
          int* p = NULL;
          *p=100;
        }
  }
}
int main()
{
  pthread_t tid[NUM];
  for(int i=0;i<NUM;i++ )
  {
    pthread_create(&tid[i],NULL,pthread_run,(void*)&i);
    sleep(1);
  }

 while(1)
 {
     printf("我是主线程, 我的thread ID: %lu\n", pthread_self());

     printf("#########################begin########################\n");
     for(int i = 0; i < NUM; ++i){
         printf("我创建的线程[%d]是: %lu\n", i, tid[i]);
     }
     printf("#########################end########################\n");
     sleep(1);
 }

  return 0;
}

当运行一段时间之后,因为野指针,说明线程一定会崩溃,那么整个进程呢?
在这里插入图片描述
在这里插入图片描述
我们发现整个进程都崩溃了,这就是线程的异常会引起进程的异常。

六、线程用途

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

例如,当我们下载视频软件时,使用多线程就能实现边下载边观看,就是在一个线程执行下载任务时,另外一个线程执行播放任务。


下一篇文章进入线程的控制章节。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Linux】线程详解之线程概念 的相关文章

  • 我应该使用哪个 Linux 发行版作为 Xen 主机? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我为家庭办公室订购了一台服务器 我想用 Xen 对其进行分区 我认为这将使事情保持干净并且更容易维护 我将运行 MySQL PostgreSQL
  • perf stat中的cycles注释是什么意思

    8 014196 task clock 0 004 CPUs utilized 204 context switches 0 025 M sec 32 cpu migrations 0 004 M sec 0 page faults 0 0
  • 进程名称长度的最大允许限制是多少?

    进程名称允许的最大长度是多少 我正在读取进程名称 proc pid stat文件 我想知道我需要的最大缓冲区 我很确定有一个可配置的限制 但就是找不到它在哪里 根据man 2 prctl http man7 org linux man pa
  • 如何在 Linux 主机上的 docker 容器中挂载目录 [重复]

    这个问题在这里已经有答案了 我想将一个目录从 docker 容器挂载到本地文件系统 该目录是网站根目录 我需要能够使用任何编辑器在本地计算机上编辑它 我知道我可以跑docker run v local path container path
  • “grep -q”的意义是什么

    我正在阅读 grep 手册页 并遇到了 q 选项 它告诉 grep 不向标准输出写入任何内容 如果发现任何匹配 即使检测到错误 也立即以零状态退出 我不明白为什么这可能是理想或有用的行为 在一个程序中 其原因似乎是从标准输入读取 处理 写入
  • Linux 上的 Python 3.6 tkinter 窗口图标错误

    我正在从 Python GUI 编程手册 学习 Python GUI 某项任务要求我通过将以下代码添加到我的配方中来更改窗口图标 Change the main windows icon win iconbitmap r C Python3
  • 无法仅在控制台中启动 androidstudio

    你好 我的问题是下一个 我下载了Android Studio如果我去 路径 android studio bin 我执行studio sh 我收到以下错误 No JDK found Please validate either STUDIO
  • touch命令在一个目录下创建多个文件(不同名称)

    我想制作一个在 bash 中创建目录和文件结构的脚本 我尝试过这样的事情 mkdir p 1 2 touch 1 2 a b c a b c 应该是在一个命令或其他命令中创建的文件 但由于某种原因 结构是这样的 current folder
  • 如何用X11复制到剪贴板?

    使用 OS X 上的框架 我可以使用以下命令将 PNG 复制到粘贴板 在 C 中 显然我可以将 NSPasteboard 与 Cocoa 一起使用 include
  • 怎样才能使 Windows 成为一个开箱即用的 POSIX 兼容操作系统?

    这个问题的动机是我的一个牵强的梦想 即 nix 平台上可用的许多优秀软件可以轻松移植到 Windows 微软最近对开源和开放性采取了不同的方法 所以我真的很想知道如果微软有这样的倾向 这样的事情会有多可行 我很好奇的一些更具体的事情是 是否
  • 停止服务时单元陷入故障状态(状态=143)[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 这是我的问题 我有 CentOS 和 java 进程在上面运行 Java进程是通过启动 停止脚本来操作的 它也创建了 java 实例的 p
  • 为什么在 Linux 上字符串文字的内存地址与其他字符串文字的内存地址如此不同?

    我注意到字符串文字在内存中的地址与其他常量和变量 Linux 操作系统 非常不同 它们有许多前导零 未打印 Example const char h Hi int i 1 printf p n void h printf p n void
  • Linux 中热插拔设备时检测设备是否存在

    我正在运行 SPIcode http lxr free electrons com source drivers spi spi omap2 mcspi c在熊猫板上 我想知道其中的哪个功能code http lxr free electr
  • 为 Qt 应用程序创建 Linux 安装

    我刚刚用 Qt Creator 制作了一个很棒的程序 我对自己很满意 如何将其从台式机移至笔记本电脑 那么 最好的方法是安装程序 对吗 对于 Ubuntu 这是一个 Debian 软件包 对吗 我怎么做 有人这样做过吗 他们可以分享 QT
  • 如何以编程方式从Linux中的进程名称获取进程ID

    在我的项目中 我们使用 ACE 自适应通信环境 中间件来编写可在 Windows 和 Linux 上运行的独立于操作系统的代码 要求是从进程名称中获取进程 ID 由于 ACE 不支持这一点 因此我们必须使用特定于平台的宏来分离 Window
  • Linux shell 脚本:十六进制数字到二进制字符串

    我正在 shell 脚本中寻找一些简单的方法来将十六进制数字转换为 0 和 1 字符的序列 Example 5F gt 01011111 是否有任何命令或简单的方法来完成它 或者我应该为其编写一些开关 echo ibase 16 obase
  • 如何让“grep”从文件中读取模式?

    假设有一个很大的文本文件 我只想打印与某些模式不匹配的行 显然 我可以使用egrep v patter1 pattern2 pattern3 现在 如果所有这些模式都在一个文本文件中怎么办 最好的制作方法是什么egrep从文件中读取模式 g
  • sleep 0 有特殊含义吗?

    我看到很多用法sleep 0在我的一个客户项目中 代码看起来像这样 while true sleep 0 end 阅读一些像这样的答案this https stackoverflow com questions 3727420 signif
  • 让 MongoDB 在 Linux 上监听远程连接

    我已在 Windows 本地计算机上 上成功安装 MongoDB 作为服务 但现在我想将 MongoDb 移动到单独的服务器 所以我将 tarball 解压到网络上的虚拟服务器 运行 Linux 当我从本地计算机使用 PuTTY 连接到服务
  • diff 文件仅比较每行的前 n 个字符

    我有2个文件 我们将它们称为 md5s1 txt 和 md5s2 txt 两者都包含a的输出 find type f print0 xargs 0 md5sum sort gt md5s txt 不同目录下的命令 许多文件被重命名 但内容保

随机推荐

  • Spring源码阅读-getBean逻辑分析记录

    getBean 从缓存中获取Bean Object sharedInstance getSingleton beanName 上述代码会从三个map中读取缓存的Bean 这三个map也是俗称的 this singletonObjects 一
  • ip2region的使用,来自csdn的回答

    使用Go语言使用ip2region库的例子如下 导入ip2region包 import github com lionsoul2014 ip2region binding golang ip2region 加载ip2region的数据库文件
  • JDK1.8函数式接口Function、Consumer、Predicate、Supplier

    JDK1 8函数式接口Function Consumer Predicate Supplier 1 函数式接口定义 函数式接口 Functional Interface 有且仅有一个抽象方法的接口 但可以有多个非抽象方法的接口 函数式接口
  • c++ 中map 的find 用法

    用find函数来定位数据出现位置 它返回的一个迭代器 当数据出现时 它返回数据所在位置的迭代器 如果map中没有要查找的数据 它返回的迭代器等于end函数返回的迭代器 程序演示 include
  • java.lang.String cannot be cast to [Ljava.lang.Object;错误的原因及解决办法

    错误信息 java lang ClassCastException java lang String cannot be cast to Ljava lang Object at com six biz impl ReportBizImpl
  • 认识网络、几种常用的网络拓扑图

    交换协议 VLAN技术 虚拟局域网 STP技术 生成树协议 VRRP技术 虚拟路由冗余协议 VPN 虚拟专用网络 名词解释 路由协议 http HTTPS tcp ip 静态路由配置 OSPF协议 RIP协议 ACL访问控制 什么是网络 简
  • 【100天精通python】Day38:GUI界面编程_PyQt 从入门到实战(中)_数据库操作与多线程编程

    目录 专栏导读 4 数据库操作 4 1 连接数据库 4 2 执行 SQL 查询和更新 4 3 使用模型和视图显示数据 5 多线程编程 5 1 多线程编程的概念和优势 5 2 在 PyQt 中使用多线程 5 3 处理多线程间的同步和通信问题
  • 论文带读——3D Neural Field Generation using Triplane Diffusion

    论文带读 3D Neural Field Generation using Triplane Diffusion YssssMikey Tips 我会基本上几天更新一篇论文引读 一般是AIGC模型 3D Diffusion方向每日在Arxi
  • JDBC的实现(IDEA版)

    前期准备 开发环境 IDEA 2021 1 3 JAVA 1 8 MYSQL 8 0 32 msql用户名 root 密码 123 下载MySQL JDBC 驱动 前往MySQL官网下载对应版本的MySQL Connector J驱动 下载
  • pix2pix gan_用python构建pix2pix gan

    pix2pix gan There are times that we want to to transform an image into another style Let s say we have a fine collection
  • 基于WOA-SVM算法的乳腺肿瘤识别算法的MATLAB仿真

    基于WOA SVM算法的乳腺肿瘤识别算法的MATLAB仿真 随着医疗技术的发展 计算机在医学影像领域中的应用越来越广泛 乳腺肿瘤是女性常见的一种肿瘤 准确地进行乳腺肿瘤检测和诊断对女性健康至关重要 本文将介绍一种基于WOA SVM算法的乳腺
  • centos下git相关操作以及部分问题解决方案

    主要记录两件事情 一个是如何git clone github代码到本地 二是git clone到非空文件夹下出错的解决方案 第一 在电脑没有安装git的情况下 手动安装git 具体步骤如下 1 安装依赖的包 yum install curl
  • c++使用curl库发送https请求

    一 环境win7 64位 vs2010 二 文件准备 2 1文件下载 libcurl 下载页面 http curl haxx se download html 我下载的是https curl haxx se download curl 7
  • angular项目打包发布流程

    1 从git更新代码 运行测试看有没有错误 测试ie兼容性 2 修改配置文件并编译打包代码 修改连接服务器的配置文件 双击 3 拷贝文件到服务器 xshell连接到linux 命令 pwd 查看当然文件目录 ll 列出该文件下所有的文件列表
  • Visual Studio 2019解决右侧工具栏消失

    项目场景 准备打开Visual Studio 2019却发现右侧的工具栏消失了 问题描述 新建项目后发现右侧的解决方案资源管理器消失了 不便于添加源文件书写代码 如图 原因分析 可能是以前在操作中将项目移除或删除等等将窗口删掉了 解决方案
  • 用jquery实现简单的表单验证效果

    看了 锋利的jquery 一书 练习了下期中的一个用jquery写表单验证的例子 效果如图 总结 这是个比较简单的表单验证 主要验证了表单中的用户名和邮箱两个必填选项 表单验证其实质是个不断往下过滤的过程 主要思路
  • selenium自动化录入数据

    将csv或者txt里的数据通过selenium自动录入到网页系统里 输入一个数据操作完后自动输入下一个数据 依次遍历所有的数据 比如百度搜索 有十个词要搜索 输入第一个词搜出结果后再接着输入第二个继续搜 依次遍历十个 求大神赐教 给个思路或
  • 21天打卡挑战学习MySQL——《SQL基础入门》第二周 第四篇

    活动地址 CSDN21天学习挑战赛 一 什么是SQL MySQL是一个关系型数据库管理系统 前世 瑞典MySQLAB公司 今生 属于Oracle旗下产品 MySQL是最好的RDBMS Relational Database Manageme
  • Unity游戏界面点击深色模式,游戏会退出问题的解决方法

    问题 在Unity游戏接入到android平台上时 经常会遇到这样的问题 游戏玩着玩着 点击深色模式 游戏会突然退出 具体情形下图所示 一 点击深色模式游戏退出 二 正常情况 三 解决方法 在AndroidManifest xml里 对继承
  • 【Linux】线程详解之线程概念

    前言 在我们的教材中 对线程给出以下的概念 是进程内部的一个执行分支 在进程的内部运行 属于进程的一部分 比进程更加轻量化 可能有的人看完之后都是懵的 什么叫在进程的内部运行 什么又是执行分支 为什么比进程轻量化 我们就带着这三个问题 重新