赞
踩
一、实验目的 |
|
二.实验环境 |
1、操作系统:Linux 2、编程语言:C语言 3、编译器:gcc |
三、实验内容与步骤 |
一、建立一个pipe,同时父进程产生一个子进程,子进程向pipe中写入一个字符串,父进程读出该字符串,并每隔3秒钟输出打印一次: 1、代码:
该程序使用了Linux系统的C语言编写,主要实现了进程间通信的管道机制。 程序首先定义了一个名为fd的整型数组,用来存储管道的读写端。然后,程序进入一个无限循环,在每次循环中通过fork函数创建一个子进程,子进程向管道写入一条消息并在3秒钟后退出,父进程等待子进程结束后从管道中读取消息并输出到控制台。 具体来说,程序在子进程中调用sprintf函数把消息字符串“Good-night!\n”存储到字符数组s中,然后使用write函数把s写入管道。父进程通过wait函数等待子进程执行完毕,并使用read函数从管道读取消息内容存储到字符数组s中。最后,父进程调用printf函数把消息内容输出到控制台。 需要注意的是,在管道读写时,需要确保读写的字节数与缓冲区大小相同,否则可能会存在数据截断或者意外读取的情况。因此,在这个程序中,使用sizeof(s)代替20作为读写长度参数,以确保读写的内容和缓冲区大小一致。 结果: 每隔3秒输出一次消息“Good-night!\n”。 二、编程实现两个子进程互斥向管道中写入信息,父进程从管道中读出信息: 1、代码:
首先,在程序开头添加了stdlib.h和unistd.h两个头文件,分别用于定义exit和sleep函数。另外,原程序中未对父进程进行处理,使得父进程也会向管道写入内容,导致数据竞争和死锁问题。为此,需要对父进程进行适当的修改。 其次,在子进程写入消息时应该使用sizeof(buf)作为写入长度参数,确保写入整个字符串。另外,在调用lockf函数时,应该先加锁再写入,写完后解锁,以防止多个进程同时写入导致的冲突问题。最后,在读取管道时,也应该使用sizeof(s)作为读取长度参数,保证读取整个字符串。 修改后的程序中,父进程等待子进程结束并从管道中读取消息,而子进程则依次向管道中写入两条消息,并在写入后立即退出。运行程序后,可以看到父进程依次读取出两条消息,并输出到控制台上。 3、结果: 可以看到,子进程依次向管道中写入了两条消息,并输出到控制台上。父进程在等待子进程结束后,从管道中依次读取出了两条消息,并输出到控制台上。因此,程序的运行结果是符合预期的。
1、代码:
这个程序通过创建命名管道fifo,在子进程和父进程中分别实现了数据的写入和读取,进而演示了管道(FIFO)的通信机制。 首先使用mkfifo函数创建了一个命名管道"fifo"。然后,若在命令行参数中指定了一个参数,则程序在子进程中执行数据的写入:首先使用fork函数创建了一个子进程,然后在子进程中打开命名管道文件并进行写操作,写入了26个不同的字符串,并且每次字符串中第一个字符的ASCII码值递增1,以此来演示不断更新的数据。最后关闭文件描述符并退出子进程。 如果在命令行参数中没有指定参数,则程序在父进程中执行数据的读取:打开命名管道文件,循环26次读取其中的数据,并在标准输出上打印出读取的数据。读取完毕后将缓冲区清空,并关闭文件描述符。 需要注意的是,在进行字符串比较和清空缓冲区等操作时,使用了对应的库函数strlen和memset,增强了程序的健壮性和鲁棒性。 该程序成功演示了命名管道(FIFO)的通信机制,并且使用了fork函数创建子进程,展示了多进程编程的基本格式。
结果无法输出的一个问题是父进程在读取数据之前没有等待子进程完成写入操作。这可能导致父进程在尝试读取数据时,FIFO还没有可用的数据,因此它会被阻塞。 需要进行如下输出方式: 使用命令./3 str &的作用是以子进程方式运行名为3的可执行文件,并将命令行参数设置为str,同时使程序在后台以异步方式运行。这样,程序将以子进程的方式写入数据到FIFO,而您可以继续使用终端进行其他操作。 子进程打开了FIFO,并进行了26次写入操作。每次写入的数据是string数组中的字符串,然后字符串的第一个字母逐渐增加('t' 到 'u','u' 到 'v',以此类推)。子进程将每次写入的数据打印出来。 |
四、实验总结 |
通过本次试验,我掌握了linux系统中管道通信的原理,了解了管道通信的特点,掌握了linux管道的相关函数的功能及使用方法,并了解linux管道的创建和使用,学会了如何利用管道实现进程间的通信,对进程间通信有了更深刻的了解和掌握。 |
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。