Linux系统进程的知识总结,进程与线程之间的纠葛...

来源:嵌入式ARM

当一个程序开始执行后,在开始执行到执行完毕退出这段时间内,它在内存中的部分就叫称作一个进程。

Linux 是一个多任务的操作系统,也就是说,在同一时间内,可以有多个进程同时执行。我们大家常用的单CPU计算机实际上在一个时间片段内只能执行一条指令。那么Linux是如何实现多进程的同时执行的呢?原来Linux使用了一种称为” 进程调度 “的手段,首先,为每个进程指派一定的运行时间,这个时间通常很短,短到以毫秒为单位,然后依照某种规则,从众多的进程中挑选一个投入运行,其他进程暂时等待,当正在运行的那个进程时间耗尽,或者执行完毕退出,或因某种原因暂停,Linux就会重新调度,挑选一个进程投入运行,因为每个进程占用的时间片段都很短,从使用者的角度来看,就好像多个进程同时运行一样。

在Linux中,每个进程在创建的时都会被分配一个数据结构,称为进程控制块(PCB)。PCB中包含了很多重要的信息,供系统调度和进程本事执行使用,其中最重要的莫过于进程的ID,进程的ID也被称为进程标示符,是一个非负的整数,在Linux操作性系统中唯一的标志一个进程。在最常使用的I386架构上,一个非负的整数的取值是0~32767,这也是我们所可能取到的进程ID,它就是进程的身份证号码。

僵尸进程的产生

僵尸进程就是已经结束的进程,但是还没有从进程表中删除。僵尸进程太多会导致进程表里面条目满了,进而导致系统崩溃,倒是不占用系统资源。

在进程的状态中,僵尸进程是非常特殊的一种,它已经放弃了几乎所有的内存空间,没有任何可执行代码,也不能被调度,仅仅在进程列表中保留一个为位置,记载该进程的退出状态等信息供其他进程收集,除此之外,僵尸进程不再占用任何内存空间,它需要它的父进程来给它收尸,如果父进程没安装SIGCHLD信号处理函数调用wait或waitpid()等待子进程结束,又没有显示的忽略该信号,那么它就一直处于僵尸状态。如果父进程结束了,那么init进程会自动接手这个子进程,为它收尸,他还是能够被清除的。但是如果父进程是一个循环,不会结束,那么子进程就一直处于僵尸状态。

僵尸进程产生的原因:

每个Linux进程在进程表中都有一个进入点(Entry),核心程序在执行该进程时使用到的一切信息都存储在进入点。当使用ps命令查看系统中的进程信息时,看到的就是进程表中的相关数据。当fork系统调用建立一个新的进程以后,核心进程就会在进程表中给这个新进程分配一个进入点,然后将相关信息存储在该进入点所对应的进程表中,这些信息中有一项是父进程的识别码。当这个进程走完了自己的生命周期后,它会执行exit()系统调用,此时原来进程表中的数据会被该进程的退出码、执行时所用的CPU时间等数据所取代,这些数据会一直保留到系统将它传递给它的父进程为止。由此可见,僵尸进程的出现时间实在子程序终止后,但是父进程尚未读取这些数据之前。

如何避免僵尸进程

1、父进程通过wait和waitpid等函数等待子进程结束,这会导致父进程挂起 
2、如果父进程很忙,那么可以用signal函数为SIGCHLD安装handler,因为子进程结束后,父进程会收到该信号,可以在handler中调用wait回收。 
3、如果父进程不关心子进程什么时候结束,那么可以用“singal(SIGCHLD),SIG_IGN”通知内核,自己对子进程的结束不感兴趣,那么子进程结束后,内核会回收,并不再给父进程发送信号。 
4、还有一些技巧,就是fork()两次,父进程fork一个子进程,然后继续工作,子进程fork一个孙进程后退出,那么孙进程被init接管,孙进程结束后,init会回收,不过子进程回收还要自己做。

进程 PK 线程

我们先打个比方,多线程是十字路口多线程是平面交通系统,造价低,但是红绿灯多,老堵车,而多进程是则是立交桥,虽然造价高,上下坡多耗油,但是不堵车。这是一个抽象的概念。相信大家看完会有这种感觉。

进程和线程是两个相对的概念,通常来说,一个进程可以定义程序的一个实例(Instance)。在Win32中,进程并不执行什么,它只是占据应用程序所使用的地址空间。为了让进程完成一定的工作,进程必须至少占有一个线程,正是这个线程负责包含进程地址空间中的代码。实际上,一个进程可以包含几个线程,它们可以同时执行进程地址空间中的代码。为了做到这一点,每个线程有自己的一组CPU寄存器和堆栈。每个进程中至少有 一个线程在执行其地址空间中的代码。如果没有线程执行进程地址空间中的代码,进程也就没有继续存在的理由,系统将自动清除进程及其地址空间。

多线程的实现原理

创建一个进程时,它的第一个线程称为主线程(Primary thread),由系统自动生成。然后可以由这个主线程生成额外的线程,而这些线程,又可以生成更多的线程。在运行一个多线程的程序时,从表面上看,这些线程似乎在同时运行。而实际情况并非如此,为了运行所有的这些线程,操作系统为每个独立线程安排一些CPU时间。单CPU操作系统以时间片轮转方式向线程提供时间片(Quantum),每个线程在使用完时间片后交出控制,系统再将CPU时间片分配给下一个线程。由于每个时间片足够的短,这样就给人一种假象,好像这些线程在同时运行。创建额外线程的唯一目的就是尽可能地利用CPU时间。

多线程的问题

使用多线程编程可以给程序员带来很大的灵活性,同时也使原来需要复杂技巧才能解决的问题变得容易起来。但是,不应该人为地将编写的程序分成一些碎片,让这些碎片按各自的线程执行,这不是开发应用程序的正确方法。线程很有用,但当使用线程时,可能会在解决老问题的同时产生新问题。例如要开发一个字处理程序,并想让打印功能作为单独的线程自己执行。这听起来是很好的主意,因为在打印时,用户可立即返回,开始编辑文档。但这样一来,在该文档被打印时文档中的数据就有可能被修改,打印的结果就不再是所期望的内容。也许最好不要把打印功能放在单独的线程中,不过如果一定要用多线程的话,也可以考虑用下面的方法解决:第一种方法是锁定正在打印的文档,让用户编辑其他的文档,这样在结束打印之前,该文档不会作任何修改;另一个方法可能更有效一些,即可以把该文档拷贝到一个临时文件中,打印这个临时文件的内容,同时允许用户对原来的文档进行修改。当包含文档的临时文件打印完成时,再删去这个临时文件。通过上面的分析可以看出,多线程在帮助解决问题的同时也可能带来新问题。因此有必要弄清楚,什么时候需要创建多线程,什么时候不需要多线程。总的来说,多线程往往用于在前台操作的同时还需要进行后台的计算或逻辑判断的情况。

线程的分类

在MFC中,线程被分为两类,即工作线程和用户界面线程。如果一个线程只完成后台计算,不需要和用户交互,那么可以使用工作线程;如果需要创建一个处理用户界面的线程,则应使用用户界面线程。这两者的主要区别在于,MFC框架会给用户界面线程增加一个消息循环,这样用户界面线程就可以处理自己消息队列中的消息。这样看来,如果需要在后台作一些简单的计算(如对电子表格的重算),则首先应考虑使用工作线程,而当 后台线程需要处理比较复杂的任务,确切地说,当后台线程的执行过程会随着实际情况的不同而改变时,就应该使用用户界面线程,以便能对不同的消息作出响应。

线程的优先级

当系统需要同时执行多个进程或多个线程时,有时会需要指定线程的优先级。线程的优先级一般是指这个线程的基优先级,即线程相对于本进程的相对优先级和包含此线程的进程的优先级的结合。操作系统以优先级为基础安排所有的活动线程,系统的每一个线程都被分配了一个优先级,优先级的范围从0到31。运行时,系统简单地给第一个优先级为31的线程分配CPU时间,在该线程的时间片结束后,系统给下一个优先级为31的线程分配CPU时间。当没有优先级为31的线程时,系统将开始给优先级为30的线程分配CPU时间,以此类推。除了程序员在程序中改变线程的优先级外,有时程序在执行过程中系统也会自动地动态改变线程的优先级,这是为了保证系统对终端用户的高度响应性。比如用户按了键盘上的某个键时,系统就会临时将处理WM_KEYDOWN消息的线程的优先级提高2到3。CPU按一个完整的时间片执行线程,当时间片执行完毕后,系统将该线程的优先级减1。

线程的同步

在使用多线程编程时,还有一个非常重要的问题就是线程同步。所谓线程同步是指线程之间在相互通信时避免破坏各自数据的能力。同步问题是由前面说到的Win32系统的CPU时间片分配方式引起的。虽然在某一时刻,只有一个线程占用CPU(单CPU时)时间,但是没有办法知道在什么时候,在什么地方线程被打断,这样如何保证线程之间不破坏彼此的数据就显得格外重要。在MFC中,可以使用4个同步对象来保证多线程同时运行。它们分别是临界区对象(CCriticalSection)、互斥量对象(CMutex)、信号量对象(CS emaphore)和事件对象(CEvent)。在这些对象中,临界区对象使用起来最简单,它的缺点是只能同步同一个进程中的线程。另外,还有一种基本的方法,本文称为线性化方法,即在编程过程中对一定数据的写操作都在一个线程中完成。这样,由于同一线程中的代码总是按顺序执行的,就不可能出现同时改写数据的情况。

总结:

在线程中(相对与进程而言),线程是一个更加接近执行体的概念,它可以与同进程的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。这两者都可以提高程序的并发度,提高程序运行的效率和响应的时间。线程和进程在使用上各有优缺点:线程执行开销小,但不利于资源管理和保护;而进程正好相反。根本的区别就一点:用多进程每个进程有自己的地址空间,线程则共享地址空间,在速度方面:线程产生的速度快,线程间的通讯快,切换快等,因为他们在同一地址空间内。在资源利用率方面:线程的资源率比较好也是因为他们在同一地址空间内。 在同步方面:线程使用公共变量/内存时需要使用同步机制,因为他们在同一地址空间内进程中:子进程是父进程的复制品,子进程获得父进程数据空间、堆和栈的复制品。

*声明:推送内容及图片来源于网络,部分内容会有所改动,版权归原作者所有,如来源信息有误或侵犯权益,请联系我们删除或授权事宜。

原文地址:https://www.cnblogs.com/woshijiuke/p/11491468.html

时间: 2024-11-08 08:32:29

Linux系统进程的知识总结,进程与线程之间的纠葛...的相关文章

[转帖]Linux系统进程的知识总结,进程与线程之间的纠葛...

Linux系统进程的知识总结,进程与线程之间的纠葛... https://cloud.tencent.com/developer/article/1500509 当一个程序开始执行后,在开始执行到执行完毕退出这段时间内,它在内存中的部分就叫称作一个进程. Linux 是一个多任务的操作系统,也就是说,在同一时间内,可以有多个进程同时执行.我们大家常用的单CPU计算机实际上在一个时间片段内只能执行一条指令.那么Linux是如何实现多进程的同时执行的呢?原来Linux使用了一种称为” 进程调度 “的

Linux 平台如何查看某个进程的线程数?

Linux 平台如何查看某个进程的线程数? 三种方法:1. 使用top命令,具体用法是 top -H 加上这个选项,top的每一行就不是显示一个进程,而是一个线程. 2. 使用ps命令,具体用法是 ps -xH 这样可以查看所有存在的线程,也可以使用grep作进一步的过滤.3. 使用ps命令,具体用法是 ps -mq pid 这样可以看到指定的进程产生的线程数目.更进一步,其实一些系统监控工具, 在本质上也是读取的系统产生的文件罢了.比如说进程这个事情,现在假设有进程号为 5000 的进程,查看

一篇让你明白进程与线程之间的区别与联系

前言 欢迎关注公众号:Coder编程获取最新原创技术文章和相关免费学习资料,随时随地学习技术知识! 本章主要介绍进程与线程的区别与联系相关知识点,也是我们面试过程中,经常会问到的了一个问题.希望通过这篇文章,能让大家理解相关知识点~ 涉及面试题: 1.进程与线程之间有什么区别? 2.进程.线程都各有什么特点? 3.进程之间的是怎么进行交互的呢? 4.什么是缓冲区溢出? 5.进程之间如何进行交互? 6.线程之间如何进行交互? 上面的面试题可以看出,其实都是一回事,只是换了一种提问方式,只要我们能掌

进程与线程之间的关系和区别 及 CPU调度

进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位. 线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位. 进程和线程的关系: (1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程. (2)资源分配给进程,同一进程的所有线程共享该进程的所有资源. (3)处理机分给线程,即真正在处理机上运行的是线程. (4)线程在执行过程中,需要协作同步.不同进程的线程间要利用消息通信的办法实现同步.

Linux有问必答:Linux上如何查看某个进程的线程

原创:LCTT https://linux.cn/article-5633-1.html 译者: GOLinux本文地址:https://linux.cn/article-5633-1.html2015-6-15 15:44 收藏: 9 问题: 我的程序在其内部创建并执行了多个线程,我怎样才能在该程序创建线程后监控其中单个线程?我想要看到带有它们名称的单个线程详细情况(如,CPU/内存使用率). 线程是现代操作系统上进行并行执行的一个流行的编程方面的抽象概念.当一个程序内有多个线程被叉分出用以执

【Linux】为啥查某个进程的线程,查出来的所有线程的pid不一样啊

楼上说的linux线程和进程是一样的,这个说法是错误的. 看了楼主的问题,感觉楼主是被PID给弄混了,线程进程都会有自己的ID,这个ID就叫做PID,PID是不特指进程ID,线程ID也可以叫做PID. 引用原文 The four threads will have the same PID but only when viewed from above. What you (as a user) call a PID is not what the kernel (looking from be

【基础知识】进程与线程的区别

线程是指进程内的一个执行单元,也是进程内的可调度实体.与进程的区别:(1)地址空间:进程内的一个执行单元;进程至少有一个线程;它们共享进程的地址空间;而进程有自己独立的地址空间;(2)资源拥有:进程是资源分配和拥有的单位,同一个进程内的线程共享进程的资源(3)线程是处理器调度的基本单位,但进程不是.4)二者均可并发执行. 进程和线程都是由操作系统所体会的程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性.进程和线程的区别在于: 简而言之,一个程序至少有一个进程,一个进程至少有一个线程.

进程与线程之间的区别及联系

一.定义: 1.进程:进程是一个具有独立功能的程序关于某个数据集合的以此运行活动.是系统进行资源分配和调度的独立单位,也是基本的执行单元.是一个动态的概念,是一个活动的实体.它不只是程序的代码,还包括当前的活动. 进程结构特征:由程序.数据和进程控制块三部分组成.具有独立性.并发性.异步性和动态性的特点. (1).进程的概念主要有两点: 第一,进程是一个实体.每一个进程都有它自己的地址空间,一般情况下,包括文本区域(text region)--存储处理器执行的代码,数据区域(data regio

进程和线程之间的差

时间:2014.06.25 位置:基础 ------------------------------------------------------------------------- 一.简述 进程Process和线程Thread是操作系统的基本概念.抽象而重要.下面从几个方面来分析进程和线程的差别. ------------------------------------------------------------------------- 二.分析 进程可觉得是程序运行时的一个实例.