Linux进程管理

一、实验目的

    通过进程的创建、撤销和运行加深对进程概念和进程并发执行的理解,明确进程和程序之间的区别。 

二、总体设计

    2.1背景知识

Linux 中创建子进程要使用 fork()函数,执行新的命令要使用 exec()系列函数,等待子进程结束使用 wait()函数,结束终止进程使用 exit()函数。
    fork()原型如下: pid_t fork(void);
    fork 建立一个子进程,父进程继续运行,子进程在同样的位置执行同样的程序。对于父进程,fork()返回子进程的 pid, 对于子进程, fork()返回 0。出错时返回-1。

exec 系列有 6 个函数,原型如下:
    extern char **environ;
    int execl( const char *path, const char *arg, ...);
    int execlp( const char *file, const char *arg, ...);
    int execle( const char *path, const char *arg , ..., char * const envp[]);
    int execv( const char *path, char *const argv[]);
    int execve (const char *filename, char *const argv [], char *const envp[]);
    int execvp( const char *file, char *const argv[]);

在函数 execl,execlp,和 execle 中, const char *arg 以及省略号代表的参数可被视为 arg0,arg1, ...,argn。它们合起来描述了指向 NULL 结尾的字符串的指针列表,即执行程序的参数列表。作为约定,第一个 arg 参数应该指向执行程序名自身,参数列表必须用 NULL 指针结束。

wait() , waitpid()可用来等待子进程结束。函数原型:

#include <sys/wait.h>

pid_t wait(int *stat_loc);

pid_t waitpid(pid_t pid, int *stat_loc,int options);

当进程调用 wait,它将进入睡眠状态直到有一个子进程结束。 wait 函数返回子进程的进程 id,stat_loc 中返回子进程的退出状态。

2.2 设计步骤

(1)进程的创建
    任务要求: 编写一段程序,使用系统调用 fork()创建两个子进程。当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示字符“a”;两子进程分别显示字符“b”和字符“c”。
    步骤 1: 使用 vi 或 gedit 新建一个 fork_demo.c 程序,然后拷贝清单 2-1 中的程序,使用 cc或者 gcc 编译成可执行文件 fork_demo。例如,可以使用 gcc –o fork_demo fork_demo.c 完成编译。
    步骤 2: 在命令行输入./fork_demo 运行该程序。
    2)子进程执行新任务
    任务要求: 编写一段程序,使用系统调用 fork()创建一个子进程。子进程通过系统调用 exec更换自己原有的执行代码,转去执行 Linux 命令/bin/ls (显示当前目录的列表),然后调用 exit()函数结束。父进程则调用 waitpid()等待子进程结束,并在子进程结束后显示子进程的标识符,然后正常结束。程序执行过程如图 2-1 所示。
    步骤 1: 使用 vi 或 gedit 新建一个 exec_demo.c 程序,然后拷贝清单 2-2 中的程序(该程序的执行如图 2-1 所示),使用 cc 或者 gcc 编译成可执行文件 exec_demo。例如,可以使用 gcc –o exec_demo exec_demo.c 完成编译。
    步骤 2: 在命令行输入./exec_demo 运行该程序。
    步骤 3: 观察该程序在屏幕上的显示结果,并分析。

   3)实现一个简单的 shell(命令行解释器) (此任务有一些难度,可选做)。
    要设计的 shell 类似于 sh,bash,csh 等,必须支持以下内部命令:
    cd <目录>更改当前的工作目录到另一个<目录>。如果<目录>未指定,输出当前工作目录。如果<目录>不存在,应当有适当的错误信息提示。这个命令应该也能改变 PWD 的环境变量。
    environ 列出所有环境变量字符串的设置(类似于 Unix 系统下的 env 命令)。
    echo <内容 > 显示 echo 后的内容且换行
    help 简短概要的输出你的 shell 的使用方法和基本功能。
    jobs 输出 shell 当前的一系列子进程,必须提供子进程的命名和 PID 号。
    quit,exit,bye 退出 shell。
    提示: shell 的主体就是反复下面的循环过程
    while(1){
      接收用户输入的命令行;
      解析命令行;
      if(用户命令为内部命令)
        直接处理;
      else if(用户命令为外部命令)
          创建子进程执行命令; //参考清单 2-2
        else
            提示错误的命令;
    }

三、详细设计

清单 2-1 创建进程

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main ()
{
int x;
while((x=fork())==-1);
if (x==0)
printf("a");
else
printf("b");
printf("c");
}


清单 2-2 子进程执行新任务

#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
pid_t pid;
/* fork a child process */
pid = fork();
if (pid < 0)
{ /* error occurred */
fprintf(stderr, "Fork Failed");
return 1;
}
else if (pid == 0)
{ /* 子进程 */
execlp("/bin/ls","ls",NULL);
}
else { /* 父进程 */
/* 父进程将一直等待,直到子进程运行完毕*/
wait(NULL);
printf(“Child Complete”);
}
        return 0;
}


四、实验结果与分析

(1) 创建进程

  因为主进程和子进程的返回值不同,所以主进程输出bc,子进程输出ac。

  运行结果如下图:

      

(2)子进程执行新任务

对于父进程,fork()返回子进程的 pid, 对于子进程, fork()返回 0。出错时返回-1

  pid = fork();创建子进程,并且接受返回值。

  如果pid<0,那么为-1出错。否则如果是子进程调用执行函数,如果是父进程则进入等待子进程,子进程运行完毕则运行父进程。

运行结果如下图:

    

五、小结与心得体会

     通过 本实验,我对 进程的创建、撤销和运行 以及对 进程概念和进程并发执行 有了更深 的理解,明确 进程和程序之间的区别。 进程是程序的一次运行活动,属于一种动态的概念

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我的书包哪里去了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值