进程控制块PCB - process control block
进程号pid唯一的标识了一个进程。
>> OS是根据PCB来对并发执行的进程进行控制和管理的。系统在创建一个进程的时候会开辟一段内存空间存放
与此进程相关的PCB数据结构。
>> PCB是操作系统中最重要的记录型数据结构。PCB中记录了用于描述进程进展情况及控制进程运行所需的全部信息。
>> PCB是进程存在的唯一标志,在Linux中PCB存放在task_struct结构体中。
进程号pid
---- 每个进程都由一个进程号来标识,其类型为pid_t,进程号的范围:0~32767。进程的数量不能超过32767。
---- 进程号总是唯一的,但进程号可以重用。当一个进程终止后,其进程号就可以再次使用了。
---- 在linux系统中进程号由0开始。进程号为0及1的进程由内核创建。
进程号为0的进程通常是调度进程,常被称为交换进程(swapper)。进程号为1的进程通常是init进程。
除调度进程外,在linux下面所有的进程都由init进程直接或者间接创建。进程的替换:exec函数。
进程控制
>> 进程号(PID):标识进程的一个非负整型数。
>> 父进程号(PPID):任何进程(除init进程外)都是由另一个进程创建。
该进程称为被创建进程的父进程,对应的进程号称为父进程号(PPID)。
>> 进程组号(PGID):进程组是一个或多个进程的集合。
他们之间相互关联,进程组可以接收同一终端的各种信号,关联的进程有一个进程组号(PGID)。
可将一个外来的进程加入到进程组中,也可以将进程组中的某个进程逐出进程组。
PGID一般是该组内第一个进程的进程号。
./可执行文件-方式运行的程序一般是一个进程组,该程序的进程号是该进程组的PGID。
pid_t getpid(void);功能:获取本进程的进程号PID。
pid_t getppid(void); 功能:获取调用此函数的进程的父进程号PPID。
pid_t getpgid(pid_t pid); 功能:获取进程组号PGID,参数为0时返回当前PGID,否则返回参数指定的进程的PGID。
#include <signal.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int
main()
{
pid_t gid;
pid_t p_gid;
pid_t p_pid;
char * path = "/opt/synopsys/M-2017.06-1/SLS/linux/vpexplorer/vpexplorer";
char * exec_argv[] = {"vpexplorer","-c","/home/yanxia.dong/linux_code/export/vpconfigs/Default/Default.vpcfg","-r",NULL};
//char * path = "/bin/bash";
//char * exec_argv[] = {"bash","-c","vpexplorer -c ./export/vpconfigs/Default/Default.vpcfg -r &",NULL};
pid_t pid = fork();
switch(pid){
case -1:
printf("fork error.\n");
return -1;
case 0:
printf("in child: group id = %d\n",getpgrp());
p_pid = getppid();
printf("in child: father pid = %d\n",p_pid);
if(setpgid(getpid(),0)==-1){
printf("in child: change gid error.\n");
}else{
printf("in child: new group id = %d\n",getpgrp());
}
if(execvp(path,exec_argv) == -1){
printf("execl error.\n");
return -1;
}
default:
printf("in father: child id = %d\n",pid);
printf("in father: parent id = %d\n",getpid());//father process pid
gid = getpgrp(); //get group pid
printf("in father: process group id = %d\n",gid);
p_gid = setpgid(pid,pid);
if(p_gid == 0){
printf("in father change child pgid success.\n");
}
sleep(60); //wait 60s
printf("sleep 60s is over.\n");
int kill_val;
kill_val = kill(-pid,SIGKILL);
printf("kill_val = %d\n",kill_val);
if(errno != 0){
printf("errno = %d.\n",errno);
}
pid_t wait_pid;
wait_pid = wait(NULL);//wait any child process
printf("wait pid = %d\n",wait_pid);
//wait(&pid); //wait the child process which process id is pid.
//sleep(100); //100s
printf("execvp done.\n");
return 0;
}
}
编译和执行结果如下: