根据提供的文件信息,我们可以归纳出以下关键知识点,主要围绕操作系统中的进程管理和管道通信技术: ### 操作系统实验:进程管理与管道通信 #### 一、基本概念 在本实验中,我们将通过创建父子进程的方式,实现子进程计算圆面积,而父进程负责打印计算结果的功能。这里涉及到的主要技术包括: - **进程**:一个正在运行的程序实例。 - **子进程**:由父进程创建的新进程。 - **父进程**:创建子进程的原始进程。 - **管道通信**:一种用于进程间通信的机制,允许数据在一个进程和另一个进程之间流动。 #### 二、进程管理 1. **fork()函数**: - `fork()` 是创建新进程的标准方法。 - 当调用 `fork()` 时,它会在当前进程中创建一个新的子进程,两个进程共享相同的代码段但拥有独立的数据段和栈段。 - `fork()` 的返回值可以用来区分父进程和子进程:在父进程中返回子进程的 PID,在子进程中返回 0。 2. **vfork()函数**: - `vfork()` 是 `fork()` 的一个变体,它主要用于提高性能。 - 调用 `vfork()` 后,子进程与父进程共享内存空间,直到子进程调用 `exec()` 或者 `exit()`。 - 在某些情况下,`vfork()` 可能会导致数据竞争问题,因此在实际应用中需要谨慎使用。 #### 三、管道通信 1. **管道(Pipe)**: - 管道是一种特殊的文件,只存在于内存中,用于连接两个进程。 - 一个管道具有两个端点:读端和写端。 - 数据只能单向流动,即从写端流向读端。 - 管道适用于有亲缘关系的进程之间的通信。 2. **管道的创建与使用**: - 使用 `pipe()` 函数创建管道,它会创建一个包含两个文件描述符的数组,一个用于写入,一个用于读取。 - 子进程通常负责写入管道,而父进程则负责从管道中读取数据。 #### 四、实验代码分析 1. **Version 1:使用 vfork()**: - 该版本使用了 `vfork()` 来创建子进程,并计算圆面积。 - 子进程中计算圆面积并打印结果。 - 父进程中等待子进程结束,并尝试打印圆面积(这一步存在问题,因为圆面积是由子进程计算并打印的)。 - 此版本存在一个问题:父进程中打印的圆面积实际上并没有被计算,因此结果可能是错误的或未定义的。 2. **Version 2:使用管道进行通信**: - 该版本使用管道来进行进程间的通信。 - 子进程计算圆面积后,将结果转换为字符串并通过管道写入。 - 父进程从管道读取字符串并打印。 - 这种方式实现了有效的数据传输,但是需要确保正确的关闭管道两端,避免资源泄漏。 3. **Version 3:使用内存映射文件(mmap)**: - 该版本利用内存映射文件实现进程间的共享内存通信。 - 子进程计算圆面积后,将结果存储到共享内存区域。 - 父进程从共享内存区域读取圆面积并打印。 - 使用内存映射文件可以实现高效的数据交换,但是需要注意同步问题和内存管理。 ### 总结 本实验通过具体的代码示例介绍了如何在 Linux 操作系统中使用进程管理和管道通信来完成特定的任务。这些技术是操作系统中非常基础且重要的组成部分,对于理解和开发多进程或多线程应用有着至关重要的作用。通过实践,不仅可以加深对这些概念的理解,还能学会如何有效地利用它们来解决问题。
version1: vfork() vfork最早起源于2.9BSD,它与fork的不同就在于它并不将父进程的地址空间完全复制到子进程中,因 为子进程会立即调用exec.vfork出来的子进程是在父进程的空间中运行的,它的存在就是为了exec调用,所以它不需要复制这些东西,因为复制了也 没有用。如果这时子进程修改了某个变量,这将影响到父进程。 vfork与fork的另一区别是:vfork保证子进程先运行,在它调用exec或exit后父进程才可能调度运行。而fork的父子进程运行顺序是不定的,它取决于内核的调度算法。
共享内存的优点是速度快,缺点嘛,显而易见。
int main(){
pid_t pc, pr;
float r = 2, area;
const float P = 3.14;
pc = vfork();
if(pc < 0){
printf("error\n");
}else if(pc == 0){
printf("child..\n");
area = P*r*r;
printf("area = %f \n", area);
sleep(1);
}else{
printf("parent..\n");
pr = wait(NULL);
printf("area = %f \n", area);
}
exit(0);
}
version 2 简单版:
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int main(){
int pipes[2];
pid_t pc;
float banjing = 2.0;
float mianji;
char a[20];
int i;
if(pipe(pipes) == 0){
pc = fork();
if(pc == -1){
fprintf(stderr, "fork failure");
exit(EXIT_FAILURE);
}
if(pc == 0){
mianji = 3.14 * banjing * banjing;
gcvt(mianji,10,a);
i = write(pipes[1],a,20);
exit(EXIT_SUCCESS);
}
else{
i = read(pipes[0],a,20);
printf("The area is: %s\n",a);
}
剩余6页未读,继续阅读
- 粉丝: 1
- 资源: 11
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 9a0f3e58cbb2b13855df377b794dc336.jpg
- (源码)基于SpringBoot和Vue的停车场管理系统.zip
- 中国地质大学(武汉)地理信息系统(GIS)考试试题整理.doc
- (源码)基于Redis的内存数据库管理系统.zip
- rv1126-rv1109-add-camera-gc2053-gc4653-②
- C#.NET酒店宾馆客房管理系统源码数据库 SQL2008源码类型 WinForm
- visual-modflow-4.X使用教程.pdf
- 水仙花数的四种实现方式(C/Java/Python/JavaScript)
- (源码)基于TensorflowLite的AI狗识别系统.zip
- (源码)基于Qt框架的3D点云与模型可视化系统.zip