Examples

linux线程控制-1

记录一下腾讯视频肖堃老师讲解的linux线程。

 

进程的概念体现出两个特点:资源(代码和数据空间、打开的文件等)以及调度/执行。线程是进程内的独立执行代码的实体和调度单元。

进程,重点体现两个特点,一个是资源的概念,进程包括内核空间的资源 ,比如说PCB、打开的文件、和用户空间的资源、代码和数据空间,同时又是一个调度执行的概念,它具有优先级,具有时间定时器、以及相应的队列等等。

线程, 则是进程内独立执行代码的实体和调度单元,线程更加的轻量些,重点体现在调度,而不是资源的分配

 

 


一个进程内的所有线程共享进程的很多资源(这种共享又带来了同步问题)

 

线程间共享
1)进程指令
2)全局变量
3)打开的文件
4)信号处理程序
5)当前工作目录
6)用户ID和组ID

 


线程私有

 

1)线程ID
2)寄存器集合(包括PC和栈指针)
3)栈(用于存放局部变量)
4)信号掩码
5)优先级

 那么进程和线程的配合分别解决什么样的问题呢?

进程是资源分配的单位。每一个进程都有自己的内存空间管理,通过内存空间管理的结构,我们让每一个进程可以有自己的,与其他进程不同的,相互之间隔离的一个地址空间。那么这在带来了安全性的保证的同时,也带来了一些编程上操作上的不方便。比如说进程和进程之间的数据难以实现共享,比如说全局变量没有办法跨进程来实现访问,等等。

 

那么为了解决这些问题,操作系统通常会引入线程。线程可以共享进程的很多资源,同一个进程当中的不同线程可以共享进程的指令、进程的全局变量、进程打开的文件、进程的用户属性等等。那么这些共享在为我们编程提供便利的同时又带来了同步的问题 ,所以进程之间的隔离以及线程之间的共享,相互都存在着优点和缺点。操作系统编程也就是在这些优点和缺点之间来取得平衡。

 

 

 

 

线程和进程的对比,通过一幅图能够非常清晰的予以展现。通过fork创建子进程的一幅图,可以看到,在创建进程的时候,必须为它分配相应的资源,那么子进程会拷贝父进程的数据段、堆以及栈,当然在某些情况下,子进程可以与父进程共享代码段。

通过线程来创建一个子线程,可以看到,资源分配几乎可以忽略不计,每一个线程只会创建一个自己独立的栈。

 

 

线程只拥有少量在运行中必不可少的资源
1)PC指针:标识当前线程执行的位置
2)寄存器:当前线程执行的上下文环境
3)栈:用于实现函数调用、局部变量(局部变量是私有的)

 

进程占用资源多,线程占用资源少,使用灵活。
线程不能脱离进程而存在,线程的层次关系,执行顺序并不明显,会增加程序的复杂度。
没有通过代码显示创建线程的进程,可以看成是只要一个线程的进程。

 

线程所拥有的资源是非常少,他只拥有三个最重要的资源:
一是标识当前线程执行位置的PC指针,
二是当前线程执行上下文环境,存放在寄存器当中。
三是线程自己的栈,栈用于实现函数调用和局部变量。

 

我们已经了解到线程的目的是为了共享进程当中的全局变量,但是线程之间能不能有自己独立的数据单元呢,这个当然可以,那就是局部的变量。

综合而言,进程占用的资源多,线程占用的资源少,所以线程的使用更为灵活。但是线程不能脱离进程而存在。线程的层次关系, 执行顺序不如进程这样清晰明显,会增加程序的复杂度。

 

那么我们所编写的很多程序,只有一个main函数,而没有在main函数当中通过代码来显示的创建线程,对于这种程序被加载以后所实现的进程而言,那么它是不是一个没有线程的进程呢,实际上并不是这样,

我们可以将没有通过代码显示创建线程的进程看成是只有一个线程,只有一个主线程的进程。

 

进程的操作和线程的操作也是类似的,可以通过一张表格清晰的进行一个类比。

 

对于进程操作而言,有创建子进程,那么对于线程操作,同样有创建子线程(pthread_create函数),

对于进程操作我们可以通过exit,来结束一个进程的生命周期,终止一个进程。 也可以通过pthread_exit来终止一个线程的生命周期,来退出一个线程 。

进程里我们可以通过wait、waitpid函数来等待某个子进程或者某一些子进程的状态改变,而在线程操作当中,我们可以通过pthread_join函数来等待某个子线程的状态改变,当然这个pthread_join函数只能等待子线程的状态变为终止 .

对于进程的Id,可以通过getpid()来获取,而对于线程的Id,可以通过pthread_self函数来获取。

 

首先对于线程ID的获取:

线程ID和进程ID一样,每一个线程也有一个ID。

线程的操作都是通过线程ID来指示,那和进程ID不尽相同的是,进程ID在整个系统当中是唯一的,而线程ID只在它所属的进程环境当中是唯一的,

线程ID的类型是pthread_t,在linux当中的线程ID的定义是这样的,用一个无符号的长整形来当做线程的ID,当然这一个定义对于很多类unix的操作系统,比如说MACOS,那么它的定义和linux是相同的。

获取线程ID的函数,是pthread_self(),pthread_self是让调用线程获取自己的线程ID。返回值就是调用线程自身的线程ID。

 

posted on 2020-06-02 16:34  足各火丁  阅读(169)  评论(0)    收藏  举报

导航

Examples