进程控制块和进程号

进程控制块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;
         }
}

编译和执行结果如下:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值