编写程序sender,它创建一个共享内存,然后等待用户通过终端输入一串字符,并将这串字符通过共享内存发送给receiver,最后,等待receiver应答,等到应答消息后,它接收到的应答消息显示在终端屏幕上,删除共享内存,结束程序运行。编写receiver程序,它通过共享内存接收来自sender的消息,将消息显示在终端屏幕上,然后再通过该共享内存向sender发送一个应答消息”over”,结束程序的运行。使用有名信号量或System V信号量实现两个进程对共享内存的互斥使用。
时间: 2024-02-22 09:56:13 浏览: 54
好的,这是一个经典的进程间通信问题。下面是一个基于 System V 信号量的实现方案,分为 sender 和 receiver 两个程序。
sender 程序:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <unistd.h>
#define SHM_SIZE 1024
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
};
void error(char *msg) {
perror(msg);
exit(EXIT_FAILURE);
}
int main() {
key_t key = ftok(".", 's'); // 生成共享内存的 key
int shmid = shmget(key, SHM_SIZE, IPC_CREAT | 0666); // 创建共享内存
if (shmid == -1)
error("shmget");
char *shmaddr = shmat(shmid, NULL, 0); // 映射共享内存
if (shmaddr == (char *)-1)
error("shmat");
key_t semkey = ftok(".", 't'); // 生成信号量的 key
int semid = semget(semkey, 1, IPC_CREAT | 0666); // 创建信号量
if (semid == -1)
error("semget");
union semun semarg;
semarg.val = 1;
if (semctl(semid, 0, SETVAL, semarg) == -1) // 初始化信号量
error("semctl");
printf("Enter message: ");
fgets(shmaddr, SHM_SIZE, stdin); // 从终端读取输入
shmaddr[strlen(shmaddr) - 1] = '\0'; // 去掉末尾的换行符
struct sembuf semops[1]; // 定义信号量操作
semops[0].sem_num = 0;
semops[0].sem_op = -1; // P 操作,等待信号量变为 0
semops[0].sem_flg = SEM_UNDO;
if (semop(semid, semops, 1) == -1) // 执行信号量操作
error("semop");
printf("Waiting for receiver...\n");
while (semctl(semid, 0, GETVAL, semarg) == 0) // 等待 receiver 处理完共享内存
sleep(1);
printf("Received response: %s\n", shmaddr);
if (semctl(semid, 0, IPC_RMID) == -1) // 删除信号量
error("semctl");
if (shmdt(shmaddr) == -1) // 解除共享内存映射
error("shmdt");
if (shmctl(shmid, IPC_RMID, NULL) == -1) // 删除共享内存
error("shmctl");
return 0;
}
```
receiver 程序:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#define SHM_SIZE 1024
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
};
void error(char *msg) {
perror(msg);
exit(EXIT_FAILURE);
}
int main() {
key_t key = ftok(".", 's'); // 生成共享内存的 key
int shmid = shmget(key, SHM_SIZE, 0666); // 获取共享内存
if (shmid == -1)
error("shmget");
char *shmaddr = shmat(shmid, NULL, 0); // 映射共享内存
if (shmaddr == (char *)-1)
error("shmat");
key_t semkey = ftok(".", 't'); // 生成信号量的 key
int semid = semget(semkey, 1, 0666); // 获取信号量
if (semid == -1)
error("semget");
printf("Received message: %s\n", shmaddr);
strcpy(shmaddr, "over"); // 向 sender 发送应答消息
struct sembuf semops[1]; // 定义信号量操作
semops[0].sem_num = 0;
semops[0].sem_op = 1; // V 操作,增加信号量
semops[0].sem_flg = SEM_UNDO;
if (semop(semid, semops, 1) == -1) // 执行信号量操作
error("semop");
if (shmdt(shmaddr) == -1) // 解除共享内存映射
error("shmdt");
return 0;
}
```
注意,sender 和 receiver 程序要在两个不同的终端中同时运行。如果需要在同一个终端中运行,可以将 sender 程序改为先等待 receiver 连接,再读取输入并发送消息。
阅读全文