【Linux】基础:线程的概念

news2024/11/13 23:13:04

【Linux】基础:线程的概念

摘要:本文介绍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. 代码将会放到: https://gitee.com/liu-hongtao-1/c–c–review.git ,欢迎查看!
  2. 欢迎各位点赞、评论、收藏与关注,大家的支持是我更新的动力,我会继续不断地分享更多的知识!

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

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

相关文章

2022年度笔记本十大热门品牌销量排行榜

近年来&#xff0c;由于大环境的改变&#xff0c;线上教育、线上办公等的需求使得平板电脑出货量逐步提升。同时&#xff0c;5G时代来临&#xff0c;万物互联是未来的趋势&#xff0c;手机由于操作系统和交互上的局限性&#xff0c;笔记本电脑将会扮演更加重要的角色。未来&…

Arduino开发ESP8266连接无线路由器

实现ESP8266连接一个WIFI路由器ESP8266选择多个路由器中信号将强的进行连接源代码如下/* ESP8266模块连接网络实验1、代码段1实现连接无线路由器实验2、代码段2实现esp8266搜索已存在网络中质量较好的并进行连接*/#include <ESP8266WiFi.h> // 提供 Wi-Fi 功能的库#inclu…

监控安防人员入门基础

1、 决定视频流畅程度的是以下哪个属性&#xff1f; A、分辨率 B、率上限 C、帧率 D、编码方式 题解&#xff1a;一幅完整的视频画面为一帧&#xff0c;每秒显示的帧的数目为帧率&#xff0c;帧率越高&#xff0c;视频更流畅。因此答案是&#xff1a;C 2、 关于图像分辨率和…

solr业务域配置

SolrSolr作为一个Java开发的高性能&#xff0c;用于对查询性能进行优化的全文搜索服务器&#xff0c;它的使用需要配置业务域&#xff1a;第一步是添加中文分析器上传中文分析器并解压&#xff0c;复制jar包到solr的lib文件夹下&#xff1a;cp IKAnalyzer2012FF_u1.jar /usr/lo…

FA-PEG-DBCO,DBCO-PEG-Folate,叶酸聚乙二醇环辛炔

●中文名&#xff1a;叶酸聚乙二醇环辛炔&#xff0c;叶酸聚乙二醇二苯基环辛炔&#xff0c;DBCO-PEG-叶酸 ●英文名&#xff1a;FA-PEG-DBCO &#xff0c; Folate-PEG-DBCO&#xff0c;DBCO-PEG- FA&#xff0c;DBCO-PEG-Folate&#xff0c;DBCO-PEG- Folic acid ●外观以及…

使用集简云将UpTimer同步到Notion

使用UpTimer同步到Notion 对于集简云我们应当非常熟悉了&#xff0c;之前讲过很多流程啦~ 利用集简云将Notion数据库更新订阅到Outlook和微信[1] 【干货分享】集简云 2步轻松定制个人RSS阅读器 |高效获取信息[2] 释放双手|自动化NOTION的最佳平台推荐|NOTION同步滴答清单|懒人[…

【人工智能原理自学】高维空间:机器如何面对越来越复杂的问题

&#x1f60a;你好&#xff0c;我是小航&#xff0c;一个正在变秃、变强的文艺倾年。 &#x1f514;笔记来自B站UP主Ele实验室的《小白也能听懂的人工智能原理》。 &#x1f514;本文讲解高维空间&#xff1a;机器如何面对越来越复杂的问题&#xff0c;一起卷起来叭&#xff01…

使用TortoiseGit同步项目到GitHub简单教程

1.TortoiseGit简介与安装 TortoiseGit是Git的Windows桌面可视化工具&#xff0c;通过软件的操作来实现git命令的效果&#xff0c;对git小白较友好。TortoiseGit可以通过官网https://tortoisegit.org/下载&#xff0c;下载之后即可按照普通软件的方式进行安装&#xff0c;每一步…

Could not find a version that satisfies the requriement xxx

Could not find a version that satisfies the requriement xxx1. 场景描述2. 解决办法2.1 升级pip2.2 更换镜像源2.3 查询所有安装的模块3.Awakening1. 场景描述 使用python自带的pip安装一些包时&#xff0c;总是会报以下错误 使用yum也会报一些错&#xff0c;反正就是装不上…

Windows10彻底关闭自动更新

文章目录前言无赖步骤关闭自动更新服务关闭自动更新策略效果总结前言 在写这篇总结之前&#xff0c;我已经尝试过多次关闭Win10的自动更新了&#xff0c;一般来说更新之后可以使操作系统更加健壮&#xff0c;但总会有一些原因让我们不想更新&#xff0c;比如我最近总是需要远程…

110、【树与二叉树】leetcode ——669. 修剪二叉搜索树:递归法(C++版本)

题目描述 解题思路 大题思路类似于 450.删除二叉搜索树中的节点&#xff08;递归法迭代法&#xff09; &#xff0c;区别在于删除的是某一区域的节点值&#xff0c;并且要保留区域内部的节点值。 对于第一次找到结点值小于low的情况&#xff0c;有两种&#xff1a;&#xff08…

【JavaWeb】HTML零基础入门

✨哈喽&#xff0c;进来的小伙伴们&#xff0c;你们好耶&#xff01;✨ &#x1f6f0;️&#x1f6f0;️系列专栏:【JavaWeb】 ✈️✈️本篇内容:HTML基础语法详解&#xff0c;附带综合案例。 &#x1f680;&#x1f680;代码托管平台github&#xff1a;JavaWeb代码存放仓库&am…

Python实战项目2——自动获取酷狗音乐工具

&#x1f935;‍♂️ 个人主页老虎也淘气 个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f44d;&#x1f3fb; 收藏…

vueJs中readonly与shallowReadonly函数的使用比较

01readonly()函数让一个响应式数据变为只读的,接收一个响应式数据,经过readonly加工处理一下,那么新赋值的数据都不允许修改接受一个对象 (不论是响应式还是普通的) 或是一个 ref&#xff0c;返回一个原值的只读代理页面没有更新有两种情况[1]. 数据修改了,但数据不是响应式,vu…

自主可控!万应低代码通过华为鲲鹏、麒麟等多项国产化认证及国家信息安全等级保护三级备案证明

01 万应低代码通过信息系统安全等级保护三级备案证明 凭借过硬的技术能力及完善的信息安全管理体系&#xff0c;万应低代码顺利通过“信息系统安全等级保护三级测评”&#xff08;简称&#xff1a;等保三级&#xff09;&#xff0c;正式获得由公安部核准颁发的“信息系统安全等…

Probabilistic Volumetric Fusion for Dense Monocular SLAM

论文标题&#xff1a;Probabilistic Volumetric Fusion for Dense Monocular SLAM 论文链接&#xff1a;https://arxiv.org/pdf/2210.01276.pdf 论文思想 提出了一种新的方法&#xff0c;通过利用深度密集的单眼SLAM和快速不确定性传播&#xff0c;从图像中重建三维场景 所提…

Vue如何高效通过JSX动态渲染组件

一、明确需求 如何渲染动态组件呢&#xff1f; 有一组数组结构如下&#xff1a; const arr [ { tag: van-field },// 输入框{ tag: van-cell }, // 弹出层{ tag: van-stepper } // 步进器 ] 想通过循环arr&#xff0c;拿到tag渲染对应的组件。 下面我们分析如何写才是最优。…

高校数据可视化(智慧校园)

教育数据可视化大屏有哪些内容&#xff1f; 教育数据可视化大屏能够展示和分析很多数据&#xff0c;比如&#xff1a;在校生数据分析、招生数据分析、就业数据分析、教职工数据分析&#xff0c;科研数据分析等综合数据分析。 跟传统的教学不同&#xff0c;现代教育对效果的要求…

03.字符函数和字符串函数

C语言中对字符和字符串的处理很是频繁&#xff0c;但是C语言本身是没有字符串类型的&#xff0c;字符串通常放在 常量字符串中或者字符数组中。字符串常量适用于那些对它不做修改的字符串函数。 1. 函数介绍 1.1 strlen size_t strlen ( const char * str ); ✳字符串以 \0 作…

python虚拟机集锦(2)-垃圾收集算法(2)

目录识别参考循环为什么移动无法访问的对象更好正在销毁无法访问的对象优化&#xff1a;世代收集最古老的一代识别参考循环 当GC启动时&#xff0c;它在第一个链接列表中拥有所有要扫描的容器对象。目标是移动所有无法到达的对象。由于大多数对象都是可访问的&#xff0c;因此…