操作系统 ----- 进程管理与创建

简述

进程和程序:

进程是程序的一次运行活动,属于一种动态的概念程序是一组有序的静态指令,是一种静态的概念。但是进程离开程序也就没有了存在的意义。因此,我们可以这 样说:进程是执行程序的动态过程,而程序是进程运行 的静态文本。如果我们把一部动画片的电影拷贝比拟成 一个程序,那么这部动画片的一次放映过程就可比为一 个进程。

一个进程可以执行一个或多个程序,反之同一个程序可能由几个进 程同时执行。例如:一个进程进行C源程序编译时,它要执行前处理、 词法语法分析、代码生成和优化等几个程序。反之,同一程序也可能 由多个进程同时执行,例如:上述C编译程序可能同时被几个程序执 行,它们对相同或不同的源程序分别进行编译,各自产生目标程序。 我们再次以动画片及其放映活动为例,一次电影放映活动必须放映特 定的几部动画片,这相当于一个进程需要几个程序提供服务。反之, 一部动画片可以同时在若干家电影院中放映,这相当于多个进程可以 执行几个同一程序。不过要注意的是,几家电影院放映同一部电影, 如果使用的是同一份拷贝,那么实际上是交叉进行的。但在多处理机 情况下,几个进程却完全可以同时使用一个程序副本。

在Linux中,系统为每个进程创建一个进程控制块 (Process Control Block 简称PCB)PCB是一个特定的 数据结构,包含了很多重要的信息,供系统调度和进程 本身执行使用。其中ID(Process ID)被称作进程标识 符,用来唯一标识该进程。

创建进程

在Linux当中,创建一个子进程需要的也是一个fork()函数(子进程当中返回的是0,父进程当中返回的是子进程的PID),这个函数是在父进程当中创建一个和父进程相同的进程,无论是程序,代码,还是参数都是和父进程相同的子进程。相当于克隆了一个自己。

那么,想要创建一个与父进程不一样的进程,需要用到的就是execl(),这个函数的函数声明是(Linux环境下)

#include <unistd.h>
int execl(constchar *path, const char *arg, ...); 

这个函数的作用就是,运行 path 目录下的程序,其中从第二个参数开始都是需要执行的程序的参数(特别注意的是,要用NULL来表示最后一个参数)

比如

/* 执行/bin/ls-al /ect/passwd*/ #include <unistd.h>/*** File: execl.c**/ 

int main() {
 // 执行/bin目录下的ls, 第一参数为程序名ls, 第二个参数为"al", 第三个参数为"/etc/passwd" 
   execl("/bin/ls", "ls", "-al", "/etc/passwd", (char *) 0); 
   return 0;
}

一旦在子进程使用了这个函数,那么子进程将不会复制父进程的内容,而是将自身的内容改为需要执行的程序的内容,那么就不会辛辛苦苦才创建了一个进程的克隆了。

int wait(int &status);

这个函数以为等待,等待子进程的完成,返回值int是等待的子进程的PID,status是子进程的状态

exit()

这个函数意为退出,无论程序到达了什么位置,一旦执行了exit()的系统调用,进程就会终止所有的操作,清除所有的数据结构并退出。

进程的控制

根据进程图的内容创建进程

按照这个图片的内容进行进程的创建

按照这个内容进行进程的创建,那么需要用到的合理的运用fork(),wait(),execl()这几个函数了。

利用这样的函数,就看按规则创建出符合标准的进程了。

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <sys/wait.h>

int main(){
    pid_t p1,p2,p3,p4,p5,p6,p7;
    pid_t end_pid;

    //用于记录已经完成的进程
    bool end_procress_list[7] = { false };
    int execl(const char * path, const char * arg, ...);

    if((p1 = fork()) == 0){
        execl("bin/echo","echo","I am p1",(char *) 0);
    }

    wait();

    if((p2 = fork()) == 0 ){
        execl("bin/echo","echo","I am p2",(char *) 0);
    }

    if((p3 = fork()) == 0 ){
        execl("bin/echo","echo","I am p3",(char *) 0);
    }

    do{
        end_pid = wait();

        if(end_pid == p2){
            end_procress_list[1] = true;
        }

        if(end_pid == p3){
            end_procress_list[2] = true;
        }

    }while(!end_procress_list[2]);

    if((p4 = fork()) == 0) {
        execl("bin/echo","echo","I am p4",(char *) 0);
    }

    if((p5 = fork()) == 0){
        execl("bin/echo","echo","I am p5",(char *) 0);
    }

    do{
        end_pid = wait();

        if(end_pid == p4){
            end_procress_list[3] = true;
        }

        if(end_pid == p5){
            end_procress_list[4] = true;
        }

    }while(!end_procress_list[3] || !end_procress_list[4]);

    if((p6 = fork()) == 0){
        execl("bin/echo","echo","I am p6",(char *) 0);
    }

    do{
        end_pid = wait();

        if(end_pid == p6){
            end_procress_list[5] = true;
        }

    }while(!end_procress_list[5]);

    if((p7 = fork()) == 0){
        execl("bin/echo","echo","I am p7",(char *) 0);
    }

    return 0;

}

猜你喜欢

转载自blog.csdn.net/a591243801/article/details/78821083