题目要求
在Linux平台上实现一个父进程和两个子进程的,利用管道和共享内存实现两个子进程之间的数据传输:
- 创建一个进程,并在该进程中创建一对管道和一块共享内存(大小大于64KB)。
- 使用
fork()
函数生成两个子进程。 - 调试程序,确保父进程与子进程之间可以进行双向通信。
- 调试程序,确保两个子进程之间可以通过父进程中转实现双向通信。
- 调试程序,确保两个子进程都能够访问共享内存。
- 实现两个子进程之间无冲突地访问共享内存。传输的数据块不小于32KB,每个字节的读/写操作后延时0.5ms。
实验环境
vmware17+ubuntu
进程间通信方式
进程间通信是指在多个进程之间进行数据交换和共享信息的过程。在操作系统中,有多种方式可以实现进程间通信,常见的方式包括:
-
管道(Pipe):
- 管道是一种半双工的通信机制,适用于具有亲缘关系的进程之间的通信。
- 可以通过
pipe()
系统调用创建管道,并使用read()
和write()
系统调用进行读写操作。 - 管道分为匿名管道和命名管道两种形式。
- 管道是单向的,即数据只能在一个方向上流动。
- 管道是半双工的,即数据只能在一个方向上流动,但可以在相反的方向上创建另一个管道。
- 管道是基于字节流的,没有消息边界,其在内核中实现为一个 FIFO(先进先出)的缓冲区。
-
命名管道(Named Pipe):
- 与匿名管道类似,但具有文件系统的路径名,使得无亲缘关系的进程也可以进行通信。
- 使用
mkfifo()
系统调用创建命名管道。
-
消息队列(Message Queue):
- 允许不同进程之间通过消息进行通信,消息被放置在队列中,每个消息都有一个类型标识。
- 可以通过
msgget()
、msgsnd()
和msgrcv()
等系统调用进行操作。
-
信号(Signal):
- 信号是一种异步通信机制,用于通知进程发生了某种事件,如中断、异常等。
- 可以使用
kill()
或raise()
发送信号,使用signal()
或sigaction()
安装信号处理函数。
-
共享内存(Shared Memory):
- 允许多个进程共享同一块内存区域,进程可以直接读写该内存区域。
-
shmget():创建或打开一个共享内存段。如果共享内存已经存在,则返回其标识符;如果不存在,则根据给定的键和大小创建共享内存段。
-
shmat():将共享内存段连接到调用进程的地址空间,返回共享内存段的地址。一旦共享内存段被连接,进程就可以直接访问该内存区域。
-
shmdt():将共享内存段从进程的地址空间中分离,使得该进程无法再访问该共享内存段。通常在不再需要共享内存时调用。
-
shmctl():对共享内存段进行控制操作,比如删除共享内存段、获取共享内存段的状态等。
-
共享内存不提供同步机制,因此在使用时通常需要配合其他同步机制(如信号量、互斥锁等)来保证多个进程之间的数据一致性和完整性。
-
信号量(Semaphore):
- 信号量是一种计数器,用于实现多进程对共享资源的访问控制。
- 可以使用
semget()
、semop()
和semctl()
等系统调用进行操作。
-
套接字(Socket):
- 套接字是一种网络通信机制,但也可以用于同一台主机上的进程间通信,例如基于本地域的套接字。
- 可以使用
socket()
、bind()
、listen()
、accept()
等系统调用进行创建和操作。
<