目录
第1关:进程等待
任务描述
通过上一个实训的学习,我们学会了使用fork和vfork创建子进程,在使用fork创建子进程的时候,子进程和父进程的执行顺序是无法预知的。本关我们将介绍如何使得fork创建出来的子进程先执行,随后父进程再执行。
本关任务:学会在多进程中,学会进程的等待处理。
编程要求
本关的编程任务是补全右侧代码片段中Begin至End中间的代码,具体要求如下:
补全waitProcess函数,等待子进程结束,并且返回子进程的退出的代码。
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
/************************
* 返回值: 调用成功且子进程正常退出返回退出代码,否则返回-1
*************************/
int waitProcess()
{
int status = -1;
/********** BEGIN **********/
pid_t pid;
pid = fork();
if(pid == -1){
//创建进程失败
return -1;
}
else if(pid == 0){
//子进程
sleep(2);
printf("This is child process\n");
exit(1);
}
else{
//父进程
if(waitpid(-1, &status, 0) != -1){
if(WIFEXITED(status))
return WEXITSTATUS(status);
}
exit(0);
}
/********** END **********/
return status;
}
第2关:进程创建操作-exec函数族
任务描述
在上一个实训中我们学习使用vfork函数创建新进程,本关我们将介绍如何另一种创建新进程的库函数。
本关任务:学会使用C语言在Linux系统中使用exec族的系统调用创建一个新的进程。
编程要求
本关的编程任务是补全右侧代码片段中Begin至End中间的代码,具体要求如下:
补全execlProcess函数,使用vfork函数创建进程,并在子进程中调用创建一个名为testDir的目录,在父进程中输出"Parent Process"字符串。
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
/************************
* 提示: 在子进程中如果执行exec函数失败要使用exit函数正确退出子进程
*************************/
int execlProcess()
{
pid_t pid = vfork();
if(pid == -1){
printf("创建子进程失败(%s)\n", strerror(errno));
return -1;
}
else if(pid == 0){
//子进程
/********** BEGIN **********/
if(execlp("touch", "touch", "testFile", NULL) < 0){
//执行execlp函数失败
exit(-1);
}
/********** END **********/
}
else{
//父进程
/********** BEGIN **********/
printf("Parent Process");
/********** END **********/
}
}
第3关:进程创建操作-system
任务描述
在上一关中我们学习使用exec函数族执行新的程序,本关我们将介绍如何另一种执行新的程序的库函数。
本关任务:学会使用C语言在Linux系统中使用system库函数来执行一个新的程序。
编程要求
本关的编程任务是补全右侧代码片段中Begin至End中间的代码,具体要求如下:
补全createProcess函数,使用system函数创建一个名为testDir的目录(** 调用成功返回命令的状态码,失败返回-1**)。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
/************************
* 返回值: 调用成功返回命令的状态码,失败返回-1
*************************/
int createProcess()
{
int ret = -1;
/********** BEGIN **********/
ret=system("mkdir testDir");
if(ret == -1){
return -1;
}
/********** END **********/
return ret;
}
第4关:实现一个简单的命令解析器
任务描述
本关任务:编写一个简单的命令解析器工具RShell,用于读取用户输入的简单命令,然后执行命令,并将命令执行结果打印出来。
编程要求
本关的编程任务是补全右侧代码片段中Begin至End中间的代码,具体要求如下:
补全RShell函数,实现一个简单的命令解析器工具。(提示:可以使用system函数或者fork+exec+wait。)
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
#include <errno.h>
void RShell(char *cmd[], int commandNum)
{
pid_t pid;
//for (int i = 0; i < commandNum; i++) {
int i = 0;
while(commandNum) {
pid = fork();
if (pid == -1) {
printf("创建进程失败(%s)!", strerror(errno));
return -1;
} else if (pid == 0) {
char *file;
char *point = NULL;
char *tmpArg[10];
point = strtok(cmd[i], " ");
file = point;
int index = 0;
while (point != NULL) {
if (index == 9)
break;
tmpArg[index++] = point;
point = strtok(NULL, " ");
}
char **arg = malloc(sizeof(char *) * (index + 1));
int i;
for (i = 0; i < index; i++)
arg[i] = tmpArg[i];
arg[index] = NULL;
if (execvp(file, arg) < 0) {
//执行execvp函数失败
exit(-1);
}
} else {
int status;
wait(&status);
}
commandNum--;
i++;
}
}