系统级程序设计-第二课

本文介绍了Linux进程控制的基础,包括如何使用fork()函数创建进程,创建多个并行进程的顺序,以及孤儿进程的概念。通过实例演示了进程创建、任务切换和同步,重点讲解了如何避免父进程过早退出导致的子进程问题。
摘要由CSDN通过智能技术生成


前言

Linux进程由进程启动,所有进程都应该有父进程。Linux系统中的进程结构类似树形结构,使用pstree命令可以查看当前系统中的进程树。进程树的顶端是进程init,它是系统启动后创建的第一个进程,负责启动getty进程、设置进程运行级别和回收孤儿进程等,是所有进程的祖先。
Linux系统中对进程的控制主要包括:进程创建、进程任务转变、进程同步和退出进程。Linux提供了一些与进程控制相关的接口,常用的接口为fork()、exex函数族、wait()、exit()。
这节课通过fork()函数来学习进程控制。


一、进程控制

1.创建一个进程

Linux使用fork()函数创建进程。fork函数是Linux多任务系统实现的基础,它包含在函数库unistd.h中,其函数声明如下:

#include <unistd.h>
pid_t fork(void);

完整代码见案例1

2.创建多个进程

对案例1中的代码进行修改,使用以下代码替代案例1中第七行的代码:

int i;
for(i = 0;i < 2;i ++){
     pid =  fork();
}

完整代码见案例2

3.进程的执行顺序

在案例1中,父进程先于子进程终止,子进程变为“孤儿进程”,后由进程init接收;在案例2中,创建了2个子进程,这2个子进程与父进程共同竞争资源。3个进程使用CPU的顺序不确定,由此子进程的编号不是递增关系,父进程在子进程尚未全部终止前便终止。另外,父进程是一个前台进程。当它终止退出后,会释放命令提示符,输出当前工作路径及终端提示符,但此时尚有子进程仍在执行,终端仍有信息输出,因此命令提示符会出现在输出结果最后一行的开头。
解决这种问题的方法不止一种,较为容易理解的方法是:使用sleep()函数,暂缓进程执行。
完整代码见案例3


二、案例

1.案例1

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(){//of main
    pid_t pid;
    pid = fork();//调用fork()函数创建子进程
    if(pid == -1){//of if //创建失败
        perror("fork error");
        exit(1);//退出进程,指定返回值1
    }
    else if(pid > 0){//父进程
        printf("parent process,pid = %d,ppid = %d\n",getpid(),getppid());
    }
    else if(pid == 0){//创建成功——子进程
        printf("child process,pid = %d,ppid = %d\n",getpid(),getppid());
    }
    printf("........finish........\n");
    return 0;
}

运行结果:
在这里插入图片描述

2.案例2

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(){//of main
    pid_t pid;
    int i;
    for(i = 0;i < 2;i ++){//of for //循环创建进程
        if((pid = fork()) == 0)//of if //若当前进程为子进程,便跳出循环
            break;
    }
    if(pid == -1){//of if
        perror("fork error");
        exit(1);
    }
    else if(pid > 0){//父进程
        printf("parent process,pid = %d,ppid = %d\n",getpid(),getppid());
    }
    else if(pid == 0){//子进程
        printf("I am child = %d,pid = %d,ppid = %d\n",i+1,getpid(),getppid());
    }
    printf("........finish........\n");
    return 0;
}

运行结果:
在这里插入图片描述

2.案例3

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(){//of main
    pid_t pid;
    int i;
    for(i = 0;i < 2;i ++){//of for
        if((pid = fork() == 0)//of if
            break;
    }
    if(pid == -1){//of if
        perror("fork error");
        exit(1);
    }
    else if(pid > 0){
        sleep(2);
        printf("parent process,pid = %d,ppid = %d\n",getpid(),getppid());
    }
    else if(pid == 0){
        sleep(i);
        printf("I am child = %d,pid = %d,ppid = %d\n",i+1,getpid(),getppid());
    }
    printf("........finish........\n");
    return 0;
}

运行结果:
在这里插入图片描述


总结

本节课通过三个案例对Linux的进程管理有了初步的认识,了解了init进程、孤儿进程的概念等,同样优先级的进程竞争系统资源,他们之间的执行顺序是无序的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值