linux系统 进程管理一点总结【001】

43 篇文章 0 订阅
27 篇文章 0 订阅

1.1进程状态:

运行态、就绪态、封锁态(等待态、阻塞态、挂起态)。

其中,处于运行态的进程只能等于CPU的数量,比如单核CPU 的机器只能同时一个进程在运行

处于就绪和封锁态的进程可以有很多,具体看下:



实际系统更为复杂,多了两个状态:新建态、终止态,具体如下:


以上是在内存状态的调度情况,但是当进程更加多更加复杂的时候,内存资源不足的时候,可是依然有进程创建,此时怎么办?随着需求,就有了主存和辅存:

活跃就绪:是指进程在主存并且可被调度的状态。
静止就绪(挂起就绪):是指进程被对换到辅存时的就绪状态,是不能被直接调度的状态,只有当主存中没有活跃就绪态进程,或者是挂起就绪态进程具有更高的优先级,系统将把挂起就绪态进程调回主存并转换为活跃就绪。
活跃阻塞:是指进程已在主存,一旦等待的事件产生便进入活跃就绪状态。
静止阻塞:是指进程对换到辅存时的阻塞状态,一旦等待的事件产生便进入静止就绪状态。


1.2 进程模式

用户模式:

      用户程序、应用程序、内核以外的程序。

内核模式:

     当出现系统调用、中断事件、异常等的时候,进程模式会切换到内核模式。【也就是:用户进程可以在两种模式下运行】

     可以执行机器的特权指令,并且此时不受用户甚至root用户干预,内核态高于所有用户态的运行

1.3:线程

有时也称为轻型的进程。

linux线程具有:一段可执行的程序、专用的系统堆栈空间、私有的进程控制块(task_struct 数据结构),本来应该有独立的存储空间,但是大量的线程要是都占用无力内存作为自己的独立存储空间,显然不够,代替的是独立的虚拟内存空间。【参考详情看这里:linux进程空间 Linux 用户进程内存空间详解

1.4:进程属性:

程序是静态的,是一些保存在磁盘上的可执行代码和数据的集合,而进程是动态的,是一个程序动态执行的一个过程,是系统调度的单位。

更多参考:http://book.51cto.com/art/200902/111548.htm

2:进程结构

既然进程是一个动态的过程,那么它自然也就是加载到内存里边的东西,这样可以被操作系统调度,进而处理程序的内部逻辑。加载到内存,所以它的结构涉及到保存的方式、位置。基本结构由3部分组成:代码段、数据段、堆栈段,也就是程序、数据、PCB进程控制块。而进程工作的核心便是PCB 控制的流程,因此PCB是进程存在的唯一标志,操作系统通过PCB的存在而感知进程的存在。

代码段:存放程序的可执行代码,比如对于EXE文件,里边的可执行代码是汇编代码对应的十六进制指令。

数据段:存放程序里边的常量、全局变量、静态变量。

堆栈段:分为堆和栈,其中,堆动态分配内存的变量,栈用于函数调用过程中,函数的参数以及函数内部的局部变量。

在linux中,进程控制块使用的是一个结构体:task_struct,它主要包含成员有:

进程状态

调度信息

标志符   PID

内部进程通信 : 管道、信号、信号量等

链接信息

时间和计时器

文件系统

虚拟内存

处理器信息

详情见这里:进程控制块  进程的概念与结构   理解Linux下进程的结构

当内核在为进程分配task_struct结构的内存空间的时候,实际上是一次性分配8K的物理内存空间,其中1K用来存放task_struct结构,7K用来存放 进程 的系统空间堆栈。


3.1:进程的创建

我们使用到的都是调用系统调用:fork() 和 clone(),新进程是通过复制父进程而创建的。二者区别在于:

fork是将父进程全部资源通过数据结构的复制“传给”子进程,它是无参数的

clone是有选择的将父进程资源复制给子进程,没有复制的数据结构则通过指针的复制让子进程共享,因此它是有参数的

创建过程:

系统从无力内存中为它分配一个task_struct数据结构和进程系统堆栈,新的task_struct数据结构加入到进程向量中,系统为该进程指定一个唯一的PID,之后进行资源的复制,例如:task_struct数据结构、系统空间堆栈、页表等,也就是堆栈段,而对于父进程的代码段和数据段中的全局变量不复制,仅仅通过只读方式实现与父进程的共享。

3.2进程的等待

父进程创建子进程后往往要让子进程替自己做一些辅助工作,因此父进程创建子进程后,有两种处理方式:同步等待、异步处理。

同步等待:

    等到子进程运行终止才继续进行。

    父进程调用系统调用:     

    pid_t wait3(int *status, int options,  struct rusage *rusage);
    pid_t wait4(pid_t pid, int *status, int options, struct rusage *rusage);
    wait3是等待任意一个子进程终止,wait4是等待特定的进程终止,但是目前这些函数“太古老”已经被放弃使用,取而代之的是:

   int waitpid(-1, status, options);

   int waitpid(pid, status, options);

   返回结果是子进程的pid

   man  查询结果:

  

   例子:

#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
int main( void )
{
	pid_t childpid;
	int status;
	childpid = fork();
	if ( childpid < 0 )
	{
		perror( "fork()" );
		exit( EXIT_FAILURE );
	}
	else if ( childpid == 0 )
	{
		puts( "In child process" );
		sleep( 3 );//让子进程睡眠3秒,看看父进程的行为
		printf("\tchild pid = %d\n", getpid());
		printf("\tchild ppid = %d\n", getppid());
		exit(EXIT_SUCCESS);
	}
	else
	{
	    int pid = waitpid( childpid, &status, 0 );
		puts( "in parent" );
		printf( "\treturn pid = %d\n",pid);
		printf( "\tparent pid = %d\n", getpid() );
		printf( "\tparent ppid = %d\n", getppid() );
		printf( "\tchild process exited with status %d \n", status );
	}
	exit(EXIT_SUCCESS);
}


异步处理:

     这个是我自己感觉的例子,不知道是否准确:

     ret=waitpid(-1,NULL,WNOHANG | WUNTRACED);

     WNOHANG      :若pid指定的子进程没有结束,则waitpid()函数返回0, 不予以等待。若结束,则返回该子进程的ID。
     WUNTRACED :若子进程进入暂停状态,则马上返回,但子进程的结束状态不予以理会。

更多内容:见这里

3.3进程的终止


3.4进程调度




 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值