使学生理解Linux中进程控制块的数据结构,Linux进程的创建、执行、终止、等待以及监控方法。并重点掌握fork函数的使用以及exec系列函数。
在前文中我们了解了fork函数的使用,以及写时拷贝机制的原理等,并且也学习了什么是僵尸进程,但是并没有具体讲到应如何处理僵尸进程,本次章节将对fork函数以及如何终止进程,还有僵尸进程的处理做更为详细的探讨。
在了解进程状态之前,我们先来谈一谈阻塞与挂起的两个概念。所谓阻塞,就是指进程因为等待某种资源就绪,而导致的一种不推进状态。也就是我们常说的卡住了。
在linux中fork函数是非常重要的函数,它从已存在进程中创建一个新进程。新进程为子进程,而原进程为父进程。
僵尸进程就是已经结束的进程(几乎不占计算机资源),但是它并没有从进程列表中删除。僵尸进程太多会导致操作系统的进程数目过多,从而占满了OS的进程表。进而导致无法创建新进程,致使OS崩溃。
In UNIX System terminology, a process that has terminated,but whose parent has not yet waited for it, is called a zombie. 在UNIX 系统中,一个进程结束了,但是他的父进程没有等待(调用wait / waitpid)他, 那么他将变成一个僵尸进程. 在fork()/execve()过程中,假设子进程结束时父进程仍存在,而父进程fork()之前既没安装SIGCHLD信号处理函数调用 wai
版权声明:本文为博主原创文章,转载请注明博客地址: https://blog.csdn.net/zy010101/article/details/83715103
In UNIX System terminology, a process that has terminated,but whose parent has not yet waited for it, is called a zombie.
L010Linux和androidNDK之linux避免僵尸进程,子进程退出的处理
这里的内容以Linux进程基础和Linux文本流为基础。subprocess包主要功能是执行外部的命令和程序。比如说,我需要使用wget下载文件。我在Python中调用wget程序。从这个意义上来说,subprocess的功能与shell类似。 subprocess以及常用的封装函数 当我们运行python的时候,我们都是在创建并运行一个进程。正如我们在Linux进程基础中介绍的那样,一个进程可以fork一个子进程,并让这个子进程exec另外一个程序。在Python中,我们通过标准库中的subprocess
这个系列的博客贴的都是我大二的时候学习Linux系统高级编程时的一些实验程序,都挺简单的。
我们在 进程概念与进程状态 中对 fork 函数进行了初步的介绍与使用,在这里我们来详细的学习一下 fork 函数;fork 是 Linux 中非常重要的一个系统调用函数,它用于在当前进程下创建一个新的进程,新进程是当前进程的子进程;我们可以 man 2号手册来查看 fork 函数:
在上一则发表的关于 Linux 的文章中,叙述了 Linux 的相关概念,其中就包括进程的资源,进程的状态,以及进程的属性等相关内容,在本则教程中,将着重叙述 Linux 进程管理的内容,其中就包括 Linux 进程的创建,进程的终止,进程的等待相关内容。
在Linux中,可以将进程分为前台进程和后台进程,它们的区别在于与终端的交互方式和执行状态。
重复查看代码运行状态:while :; do ps ajx | head -1 && ps ajx | grep testStatus | grep -v grep; sleep 1; done
版权声明:本文为博主原创文章,转载请注明博客地址: https://blog.csdn.net/zy010101/article/details/83690667
进程的控制 实验目的 1、掌握进程另外的创建方法 2、熟悉进程的睡眠、同步、撤消等进程控制方法 实验内容 1、用fork( )创建一个进程,再调用exec( )用新的程序替换该子进程的内容 2、利用wait( )来控制进程执行顺序 实验指导 一、所涉及的系统调用 在UNIX/LINUX中fork( )是一个非常有用的系统调用,但在UNIX/LINUX中建立进程除了fork( )之外,也可用与fork( ) 配合使用的exec( )。 1、exec( )系列 系 统调用exec( )系列,也可用于新程序的运
前言:接着前面进程终止,话不多说我们进入Linux进程等待的学习,如果你还不了解进程终止建议先了解:
什么是僵尸进程 Linux 中的僵尸进程有时也称为失效或死进程。它们是已完成执行的进程,但它们的条目并未从进程表中删除。 进程状态 Linux 维护着所有正在运行的进程及其状态的进程表。让我们简要概述各种进程状态: 正在运行 (R):这些进程当前正在运行或可运行。 等待 (S/D):这些是等待事件或资源的进程。等待可以是可中断睡眠 (S) 或不可中断睡眠 (D)。 停止(T):我们可以通过发送适当的信号来停止Linux 进程。 僵尸(Z):当一个进程完成它的任务时,它会释放它正在使用的系统资源并清理它的内存
ps 是一个常用的 Unix/Linux 命令,用于显示当前系统中运行的进程信息。它的名称来源于 “process status”(进程状态)的缩写。通过 ps 命令,您可以查看正在运行的进程的各种信息,例如进程 ID、CPU 使用情况、内存占用、进程状态等。
前言:在上一篇了解完一部分常见的进程状态后,我们先来把剩下的进程状态了解一下,再来进入进程优先级的学习!
Linux Daemon(守护进程)是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。它不需要用户输入就能运行而且提供某种服务,不是对整个系统就是对某个用户程序提供服务。
1、僵尸进程的产生 在AIX操作系统实施的进程结构中,每一个进程都有一个父进程。当一个进程结束时会通知它的父进程,从而该进程的父进程会收集该进程的状态信息。若父进程在一定的时间内无法收集到状态信息,则系统中就会残留一个僵尸进程。 因为僵尸进程是已经停止的,所以使用杀死进程的方法来杀僵尸进程是无效的。僵尸进程不使用CPU或硬盘等系统资源,而只使用极少量的内存用于存储退出状态和资源使用信息。 2、问题分析 某一个进程在结束时由它的父进程负责删除它。要找到某一个进程的父进程,执行ps -ef命令,输出中的P
守护进程(Daemon)是执行在后台的一种特殊进程。它独立于控制终端而且周期性地执行某种任务或等待处理某些发生的事件。守护进程是一种非常实用的进程。Linux的大多数server就是用守护进程实现的。比方,Internetserverinetd,Webserverhttpd等。同一时候,守护进程完毕很多系统任务。比方,作业规划进程crond,打印进程lpd等。 守护进程的编程本身并不复杂,复杂的是各种版本号的Unix的实现机制不尽同样,造成不同Unix环境下守护进程的编程规则并不一致。这须要读者注意,照搬某些书上的规则(特别是BSD4.3和低版本号的System V)到Linux会出现错误的。以下将全面介绍Linux下守护进程的编程要点并给出具体实例。 一. 守护进程及其特性 守护进程最重要的特性是后台执行。在这一点上DOS下的常驻内存程序TSR与之类似。其次,守护进程必须与其执行前的环境隔离开来。这些环境包含未关闭的文件描写叙述符,控制终端,会话和进程组,工作文件夹以及文件创建掩模等。这些环境一般是守护进程从执行它的父进程(特别是shell)中继承下来的。最后,守护进程的启动方式有其特殊之处。它能够在Linux系统启动时从启动脚本/etc/rc.d中启动,能够由作业规划进程crond启动,还能够由用户终端(一般是shell)执行。 总之,除开这些特殊性以外,守护进程与普通进程基本上没有什么差别。因此,编写守护进程实际上是把一个普通进程依照上述的守护进程的特性改造成为守护进程。假设读者对进程有比較深入的认识就更easy理解和编程了。 二. 守护进程的编程要点 前面讲过,不同Unix环境下守护进程的编程规则并不一致。所幸的是守护进程的编程原则事实上都一样,差别在于具体的实现细节不同。这个原则就是要满足守护进程的特性。同一时候,Linux是基于Syetem V的SVR4并遵循Posix标准,实现起来与BSD4相比更方便。编程要点例如以下; 1. 在后台执行。 为避免挂起控制终端将Daemon放入后台执行。方法是在进程中调用fork使父进程终止,让Daemon在子进程中后台执行。 if(pid=fork()) exit(0);//是父进程,结束父进程,子进程继续 2. 脱离控制终端,登录会话和进程组 有必要先介绍一下Linux中的进程与控制终端,登录会话和进程组之间的关系:进程属于一个进程组,进程组号(GID)就是进程组长的进程号(PID)。登录会话能够包含多个进程组。这些进程组共享一个控制终端。这个控制终端一般是创建进程的登录终端。 控制终端,登录会话和进程组一般是从父进程继承下来的。我们的目的就是要摆脱它们,使之不受它们的影响。方法是在第1点的基础上,调用setsid()使进程成为会话组长: setsid(); 说明:当进程是会话组长时setsid()调用失败。但第一点已经保证进程不是会话组长。setsid()调用成功后,进程成为新的会话组长和新的进程组长,并与原来的登录会话和进程组脱离。因为会话过程对控制终端的独占性,进程同一时候与控制终端脱离。 3. 禁止进程又一次打开控制终端 如今,进程已经成为无终端的会话组长。但它能够又一次申请打开一个控制终端。能够通过使进程不再成为会话组长来禁止进程又一次打开控制终端:
在进行堵塞式系统调用时。为避免进程陷入无限期的等待,能够为这些堵塞式系统调用设置定时器。Linux提供了alarm系统调用和SIGALRM信号实现这个功能。
标示符(pid): 描述本进程的唯一标示符,用来区别其他进程; 状态(status): 任务状态,退出代码,退出信号等; 优先级(PRI): 相对于其他进程的优先级; 程序计数器: 程序中即将被执行的下一条指令的地址; 内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针上下文数据: 进程执行时处理器的寄存器中的数据[休学例子,要加图CPU,寄存器; I/O状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表; 记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。
操作系统中的经典定义: 进程:资源分配单位。 线程:调度单位。 操作系统中用PCB(Process Control Block, 进程控制块)来描述进程。Linux中的PCB是task_struct结构体。
进程是通过fork系列的系统调用(fork、clone、vfork)来创建的,内核(或内核模块)也可以通过kernel_thread函数创建内核进程。这些创建子进程的函数本质上都完成了相同的功能——将调用进程复制一份,得到子进程。(可以通过选项参数来决定各种资源是共享、还是私有。)
退出码是用来标识一个进程任务执行结果的情况。因为成功只有一种情况,而失败的情况很多,因此,一般情况下0表示执行成功,非0表示执行失败。非0的数字不同,所表示的错误不同。系统对于退出码一般都有着相应的文字藐视,当然我们也可以自定义,也可以直接使用系统给定的映射关系。(例如,strerror这个函数)
Linux 允许进程查询内核以获得其父进程的 PID,或者其任何子进程的执行状态。例如,进程可以创建一个子进程来执行特定的任务,然后调用诸如 wait() 这样的一些库函数检查子进程是否终止。如果子进程已经终止,那么,它的终止代号将告诉父进程这个任务是否已成功地完成。
僵尸进程是指一个已经终止、但是其父进程尚未对其进行善后处理获取终止进程的有关信息的进程,这个进程被称为“僵尸进程”(zombie)。
1. 在调用fork函数之后,当执行的程序代码转移到内核中的fork代码后,内核需要分配新的内存块和内核数据结构给子进程,内核数据结构包括PCB、mm_struct和页表,然后构建起映射关系,同时将父进程内核数据结构中的部分内容拷贝到子进程,并且内核还会将子进程添加到系统进程列表当中,最后内核空间中的fork代码执行完毕,操作系统中也就已经创建出来了子进程,最后返回用户空间,父子进程执行程序fork之后的剩余代码。
进程间通信简称为 IPC(Interprocess communication),是两个不同进程间进行任务协同的必要基础。进行通信时,首先需要确保不同进程之间构建联系,其次再根据不同的使用场景选择不同的通信解决方案,本文主要介绍的通信解决方案为 匿名管道
1、我们先来看这个函数的原型和它所包含的头文件(在Linux系统下,使用man 手册来查看它的具体用法:man 2 wait):
在通常的计算机书籍或者课本中对进程概念的描述是这样的 – 进程就是被加载到内存中的程序,或者被运行起来的程序就叫做进程;这样说的原因如下:
功能:创建一个与原来进程几乎完全相同的进程,即两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。一个进程调用fork函数后,系统先给新的进程分配资源,例如,存储数据和代码的空间。然后把原来的进程所有值都复制到新的进程中,只有少数值与原来的进程的值不同。相当于克隆了一个自己。
Linux中,父进程和子进程是并行运行的,先运行哪个是不确定的,在小红帽系统(Red Hat)中,先运行的是子进程,在ubuntu系统中,父进程是先运行的。
原文地址:http://www.cnblogs.com/jacklu/p/5317406.html
在linux中fork函数时非常重要的函数,它从已存在进程中创建一个新进程。新进程为子进程,而原进程为父进程
在Linux中,都是通过fork与vfork系统调用来创建子进程,并且在fork完之后,通常会调用exec命令簇来替换代码段,执行不同的任务。而在创建子进程的时候,同时通过COW的方式创建的。
我们从实现的角度来看: 进程是一种数据结构,用描述程序运行的状态和系统变化的状态。
进程控制不仅仅是管理程序的执行顺序,还涉及到资源的分配等问题,那么话不多说,开始我们今天的话题!
上次介绍了环境变量:Linux:进程概念(四.main函数的参数、环境变量及其相关操作)
在学习廖雪峰老师的python教程,学习了多进程和多线程,记录下核心的思路和方法。
fork的头文件为unistd.h fork的返回值:父进程会返回子进程的pid,子进程返回0(一个子进程只有一个父进程,但是有个父进程可以有无数个子进程,一次要将子进程的pid返回给父进程,而子进程不需要)
该文章介绍了如何在Linux系统中通过fork函数创建子进程,并详细讲解了fork函数的工作原理、父进程和子进程之间的通信以及fork函数引发的孤儿进程和僵尸进程等问题。同时,文章还介绍了如何使用wait和waitpid函数等待子进程结束,以及如何使用exec系列函数在子进程中执行新的程序。
一个普遍的常识是,在Linux里面总是“白发人送黑发人”,子进程死亡,父进程透过wait()等待子进程死亡,并清理子进程僵尸,当然父进程也可以因此而获得子进程的死亡原因。
每一个可执行程序运行起来之后都会成为一个进程,每个进程都有一个自己的id,以及一个父进程id,父进程就是创建自己进程的进程,每个进程都是一个执行起来的程序,所以肯定在这个程序中创建另一个程序,就是自己的子进程。
领取专属 10元无门槛券
手把手带您无忧上云