您的位置:首页 > 运维架构 > Linux

Linux-查看进程

2018-03-13 18:21 239 查看

Linux的进程控制块

之前已经介绍过进程控制块的概念,那么Linux下的进程控制块具体是一个怎么样的结构下面详细说明。

在Linux的操作系统中,PCB是一个叫做task_struct的结构体,其中的内容如下:

标识符:与进程相关的唯一标识符,用来区分其他进程。

状态:进程有不同的状态,例如运行,就绪,阻塞等。

优先级:为了给处理机调度提供支持,优先级用来区分各种进程的先后执行顺序

程序计数器:程序中即将执行的下一条指令的地址

内存指针:包括程序代码的进程相关数据的指针,以及与其他进程贡献那个内存块的指针。

上下文:进程是需要切换的,切换进程时需要保留进程的上下文信息,以防进程在切换时丢失现场数据。

i/o状态信息:包括显示i/o请求,分配给进程的i/o设备和被进程使用的文件列表等。

记账信息:包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。

具体可查看:task_struct

查看进程

第一种查看进程的方式:进入到/proc这个目录下,可以查看到当前进程的系统文件夹。



下面第二种方式可以使用命令工具获取

首先我们创建一个进程,写一个循环程序。

int main()
{
while(1)
{
sleep(1);
}
return 0;
}


接下来运行,另开一个终端,查看该进程。

ps aux | grep a.out




可以看到在两条命令中间我结束了这个进程,所以再也查看不到该进程。所显示的该进程是我使用的这条命令grep这条命令的进程。

终止进程

Linux用于终止进程的命令:kill

用下面这个命令查看kill所有选项。

kill -l




9号是用来终止一个进程的。

下面我们用第一个程序来测试终止程序。

在一个终端下运行程序,在另一个终端下终止它。





获取进程标识符

进程标识符:

进程id:PID

父进程id:PPID

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
printf("PID=%d\n",getpid());
printf("PPID=%d\n",getppid());
return 0;
}




再来查看一下该进程的父进程是谁



可以看到父进程是bash。

创建进程

Linux下用fork()函数创建进程。

举例说明:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
int ret=fork();
printf("proc pid:%d ret = %d\n",getpid(),ret);
sleep(1);
return 0;
}




可以看到我们程序中只打印一句话,这里怎么打印了两句,原因是因为fork()函数调用一次,返回两次。

在return之前,我们所需要函数该做的事情都已经做完,所有意味着此时子进程已经被建立,当前就应该有两个进程,建立子进程的父进程(当前你所写的这个程序)与建立好的子进程。既然有两个进程,两个进程都要返回,所以有两个返回值。

返回成功:父进程返回子进程的PID,子进程返回0。

返回失败:父进程返回-1.子进程没有被创建。

所以一般再用fork时需要分流,子进程做子进程的事,父进程做父进程的事。

实际上:父子进程共享代码,数据各自开辟虚拟程序地址空间,采用“写时拷贝”的方式修改各自的数据。

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
int ret=fork();
if(ret==0)
{
//child
printf("child:pid=%d ret=%d\n",getpid(),ret);
}
else if(ret>0)
{
//father
printf("father:pid=%d ret=%d\n",getpid(),ret);
}
sleep(1);
return 0;
}




可以看到,fork函数确实是调用了一次却返回了两个值:父进程的返回值是子进程的pid,子进程的返回值是0,说明子进程创建成功。

fork出错可能有两种原因:

1)当前的进程数已经达到了系统规定的上限,这时errno的值被设置为EAGAIN。

2)系统内存不足,这时errno的值被设置为ENOMEM。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: