操作系统实验一:进程的建立
一、 实验目的:
-
创建进程及子进程;
-
在父子进程之间实现进程通信;
二、 实验内容:
-
创建进程并显示标识等进程控制块的属性信息;
-
显示进程的通信信息和相应的应答信息;
三、实验要求
-
显示创建的进程及控制块参数;
-
显示进程之间的关系参数;
-
实现父子进程之间通信模拟;
四、实验设计与实现:
-
设计思路:实验要求在 父子进程 之间实现进程通信,所以可以采用 fork() 函数来通过一个进程创建他的一个子进程。关于父子进程之间通信可以采用 无名管道 这一方式。无名管道是通过内核开辟一段缓存空间,进程共享这段缓存空间,通过文件描述符( write()和read() )对这段缓存空间的读写来实现进程之间的通信。一个无名管道在进程双向通信时有极大可能产生 干扰 (即父进程刚写入的信息在子进程读到之前就又被父进程读到),为了防止干扰,采用了两个 无名管道 实现 父子进程间双向通信。此外,通过 getpid()和getppid() 获取父子进程的pid标识符。
-
实验环境:Linux系统,Ubuntu 64位 20.04.2.0;
-
实验代码:
-
Pipe.c:
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<string.h> // for bzero() /* *该函数用来输出错误信息; */ void print_err(char *estr) { perror(estr); exit(-1); } int main(void) { int ret = 0; // ret变量用来接收返回值; /* * 用两个数组来存放两个管道的文件描述符; * [0]元素:存放读文件描述符; * [1]元素:存放写文件描述符; */ int pipefd1[2] = {0}; int pipefd2[2] = {0}; ret = pipe(pipefd1); // 调用pipe函数判断返回值; if(ret == -1){print_err("pipe1 fail");} ret = pipe(pipefd2); if(ret == -1){print_err("pipe2 fail");} ret = fork(); // 创建父子进程并判断返回值; if(ret == -1){print_err("fork fail");} if(ret > 0){ /* * 该段代码是父进程执行的; */ close(pipefd1[0]); // 关闭父进程管道一的读描述符(防止干扰); close(pipefd2[1]); // 关闭父进程管道二的写描述符; char buf[30] = {0}; // 定义一个缓存字符串组; int f_pid; f_pid = getpid(); int s_pid; s_pid = ret; while(1){ printf("\033[35;1m输入父进程(pid=%d)发送的消息:", f_pid); scanf("%s", buf); write(pipefd1[1], buf, sizeof(buf)); // 写入管道1; sleep(1); bzero(buf, sizeof(buf)); // 清空缓存区; read(pipefd2[0], buf, sizeof(buf)); // 读管道2; printf("\033[35;1m父进程(pid=%d)接收子进程(pid=%d)的消息: %s\n", f_pid, s_pid, buf); } } else if(ret == 0){ /* * 该段代码是子进程执行的; */ close(pipefd1[1]); //关闭子进程的写描述符; close(pipefd2[0]); char buf[30] = {0}; // 定义一个缓存字符串组; int s_pid; s_pid = getpid(); int f_pid; f_pid = getppid(); while(1){ bzero(buf, sizeof(buf)); // 清空缓存区; read(pipefd1[0], buf, sizeof(buf)); printf("\033[36;1m子进程(pid=%d)接收父进程的消息(pid=%d):%s\n", s_pid, f_pid, buf); sleep(1); printf("\033[36;1m输入子进程(pid=%d)发送的数据:", s_pid); scanf("%s", buf); write(pipefd2[1], buf, sizeof(buf)); } } return 0; }
-
五、实验结果分析:
-
在Linux终端中输入:
gcc pipe.c ./a.out
-
终端输出结果:
- 在提示下输入字符串,实现了父子进程之间的通信。
参考视频:
https://www.bilibili.com/video/BV1fE411v7Bb?p=6
https://edu.51cto.com/course/13462.html