10年专注金属丝网产品质量有保 售后7×24小时服务
24小时咨询热线:4006666666
联系我们
金属丝网设备有限公司
全国免费服务热线:4006666666
地址 :中国·北京
联系人:陈经理
您的位置: 首页>>热门话题>>正文
热门话题

[linux中的线程是怎么形成的啊]linux中的线程是怎么形成的?

时间:2023-06-03 作者:admin666ss 点击:37次

线程:线程是操作系统调度计算的基本单位。线程是进程的单个执行流,程序内的执行路径通常称为线程。

您会发现一个进程至少有一个执行线程。此线程是主执行流。一个进程的多个执行流是共享进程地址空间的资源。也就是说,进程的资源合理分配给每个执行流,形成线程执行流。因此,线程在进程内运行,本质上是在进程地址空间内运行。

请注意,Linux没有真正意义上的线程,线程是通过过程模拟的。这句话怎么理解?

在Linux系统中,没有专门为线程设计的数据结构。那个线程是怎么形成的?我们知道,在创建流程时,必须创建相关的数据结构,如PCBmm_sturct页面表file_struct等。线程生成与进程生成相同,线程也创建一个PCB。线程共享进程地址空间,因此所有线程都保留相同的进程地址空间。

这样,线程就是执行流,每个线程都有一个task_struct结构,与流程一样,这些task_struct由操作系统保留。从CPU的角度来看,进程和线程没有区别,因此Linux下的线程通过进程模拟来实现。

2976263-20221029125107066-2129229798.png [linux中的线程是怎么形成的啊]linux中的线程是怎么形成的? 热门话题

继续思考CPU在Linux中如何区分线程和进程。

事实上,CPU不需要考虑这个问题。进程和线程没有区别。全部是一个task_struct,CPU只需要负责调度。

那么,我们如何理解以前学习的过程呢?

我们都知道,进程是负责分配系统资源的基本实体。从CPU中看到的PCB是整个过程,也就是只有一个执行流的过程。您现在看到的PCB不一定是整个进程,它可以是一个进程的执行流的总分支,也就是多个执行流进程。因此,在CPU眼里,PCB比传统流程轻。具有此多个执行流的进程中的每个执行流都可以被视为轻量级进程。综上所述,线程是一个轻量级过程。

摘要:

简而言之,每个线程都有自己的PCB。但是,这些PCB维护和共享相同的虚拟空间,但线程的PCB更轻。操作系统分配资源时,将进程PCB分配为资源的最小单位,因此分配给进程的资源由属于该进程的线程共享,线程是操作系统调度的最小单位,操作系统不区分线程和线程。

复制对方的地址空间会生成流程。

共享对方的地址空间会生成线程。

可以更容易地理解进程和线程之间的差异。流程创建类似于深度复制副本,线程创建类似于浅复制副本,有助于理解

流程:负责分配系统资源的实体

线程:CPU调度的基本单位

注意:进程之间有很强的独立性,但线程相互影响

线程共享部分流程数据或唯一的数据部分。

线程ID

寄存器组

单独的堆栈空间

信号屏蔽

调度优先级

埃莉诺

处理器现场和堆栈指针

文件描述符

各信号处理方法

当前工作目录

用户ID和组ID

.text。bss共享

示意图:

2976263-20221029125124883-988070718.png [linux中的线程是怎么形成的啊]linux中的线程是怎么形成的? 热门话题

注:Linux内核没有提供线程管理的库功能。其中线程库是用户提供的线程管理功能。

错误检查:

某些现有函数成功返回0,不返回-1,为全局变量errno赋值以指示错误。

代码示例:

运行结果如下:

2976263-20221029125141902-1591598843.png [linux中的线程是怎么形成的啊]linux中的线程是怎么形成的? 热门话题

线程在生成过程中没有被阻止,主进程立即运行。这样,主进程完成后,所有线程都将释放,线程将出现未计划的问题。

线程和进程是不同的。父子进程执行相同的片段,但线程生成后执行的是线程处理函数。

再介绍一个函数。

就像每个进程都有进程号一样,每个线程也有线程号。进程号在整个系统中是唯一的,但线程号不同,线程号仅在该进程环境中有效。

示例1:创建线程以观察代码执行效果和函数的使用

运行结果如下:

2976263-20221029125159735-558765828.png [linux中的线程是怎么形成的啊]linux中的线程是怎么形成的? 热门话题

示例2:创建4个线程后打印每个PID和线程ID

运行结果如下:

2976263-20221029125213908-2083169745.png [linux中的线程是怎么形成的啊]linux中的线程是怎么形成的? 热门话题

在没有线程之前,进程与内核的进程描述符和进程ID相对应。引入线程概念后,一个用户进程管理多个用户状态线程。每个线程都作为单独的调度实体进行管理,内核中有自己的进程描述符。进程和内核的描述符成为1: n关系。

多线程进程,也称为线程组。线程组中的每个线程在内核中都有一个进程描述符。进程描述符结构表面上是进程的PID,但实际上与线程ID相对应。进程描述符的tpID,表示与用户级别的进程ID相对应的线程组ID。

具体关系如下。

用户状态

系统调用

内核进程描述符的相应结构

线程ID

Pid_t gettid

Pid_t PID

进程ID

Pid_d getpid

Pid_t tgid

注意:其中线程ID与创建线程的ID不同。其中,螺纹ID是用于唯一标识螺纹的成型变量。

如何查看线程ID?

1.可以使用带有-L选项的PS命令查看lwp

2.Linux通过提供gettid系统调用返回线程id,但glibc位于开放接口上,供程序员使用,而不封装系统调用。如果需要获取线程ID,可以使用以下方法:

如上图所示,一个线程的ID与进程ID相同。这个线程是主线程。内核称为group leader,内核在创建第一个线程时将线程组ID值设置为第一个线程的线程ID,group_leader指针指向作为主线程的进程描述符的自己。因此,“线程组”具有线程ID,它是“线程组”中的默认线程。

2976263-20221029125235758-1933423110.png [linux中的线程是怎么形成的啊]linux中的线程是怎么形成的? 热门话题

注意:线程与进程不同,线程具有父进程的概念,但线程组中的所有线程都是对等关系。

2976263-20221029125252597-1439870063.png [linux中的线程是怎么形成的啊]linux中的线程是怎么形成的? 热门话题

线程可以通过调用exit函数或_exit函数来结束进程。在一个线程中,可以通过以下三种方式停止控制流,而无需结束整个进程:

在线程函数return中。此方法不适用于主线程。相当于从main函数return调用exit。

注意:不能使用exit结束线程。exit用于结束进程。如果从线程调用exit,线程结束时,该线程的进程也会终止。

示例1:退出return线程调度程序

执行结果小伙伴们自己执行吧。

注意:取消线程不是实时的,而是有延迟的。需要等待线程到达取消点。

运行结果如下:

2976263-20221029125319843-793263424.png [linux中的线程是怎么形成的啊]linux中的线程是怎么形成的? 热门话题

线程等待的原因:

已经终止的线程不会释放空间,而是保留在进程的地址空间中。

创建新线程不会重用刚结束的线程的地址空间。

运行结果如下:

2976263-20221029125336188-819849840.png [linux中的线程是怎么形成的啊]linux中的线程是怎么形成的? 热门话题

摘要:

当Thread线程通过return返回时,retval指向的单元格将存储thread线程函数的返回值。

如果您对Thread线程的终止状态不感兴趣,可以将NULL传递给retval参数。

为了解决线程阻塞问题,为了防止阻塞造成的资源浪费,提出了线程分离。


相关推荐

发表评论