两个程序通信采用共享内存收发数据 结合信号量处理 使用C语言编写试例代码
时间: 2024-09-14 10:03:27 浏览: 82
AT89S52单片机C语言应用100例-基于AT24C02的多机通信-综合文档
在程序通信中,使用共享内存是一种高效的通信方式,因为它允许多个进程共享同一块内存空间,从而避免了数据在多个进程间复制的开销。信号量则是一种用于多进程同步的机制,用来控制对共享资源的访问。
以下是一个简单的C语言示例,展示了如何结合共享内存和信号量进行进程间通信。这个例子中包含一个生产者和一个消费者,生产者生成数据并放到共享内存中,消费者从共享内存中取出数据。
```c
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <unistd.h>
#define SEM_KEY 1234
#define SHM_KEY 5678
#define BUFFER_SIZE 100
// 定义信号量集操作的联合体
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
};
// 初始化信号量
int init_sem(int sem_id, int sem_value) {
union semun sem_union;
sem_union.val = sem_value;
if (semctl(sem_id, 0, SETVAL, sem_union) == -1;
return 0;
}
// P操作(等待)
void P(int sem_id) {
struct sembuf sem_p;
sem_p.sem_num = 0;
sem_p.sem_op = -1; // P操作
sem_p.sem_flg = SEM_UNDO;
if (semop(sem_id, &sem_p, 1) == -1) {
perror("P operation");
exit(EXIT_FAILURE);
}
}
// V操作(信号)
void V(int sem_id) {
struct sembuf sem_v;
sem_v.sem_num = 0;
sem_v.sem_op = 1; // V操作
sem_v.sem_flg = SEM_UNDO;
if (semop(sem_id, &sem_v, 1) == -1) {
perror("V operation");
exit(EXIT_FAILURE);
}
}
int main() {
// 创建共享内存
int shm_id = shmget(SHM_KEY, BUFFER_SIZE, IPC_CREAT | 0666);
if (shm_id == -1) {
perror("shmget");
exit(EXIT_FAILURE);
}
// 连接共享内存
char *buffer = (char *)shmat(shm_id, NULL, 0);
if (buffer == (char *)(-1)) {
perror("shmat");
exit(EXIT_FAILURE);
}
// 创建信号量集
int sem_id = semget(SEM_KEY, 2, IPC_CREAT | 0666);
if (sem_id == -1) {
perror("semget");
exit(EXIT_FAILURE);
}
// 初始化信号量
union semun sem_union;
init_sem(sem_id, 1); // 信号量0初始化为1,表示共享内存是空的
init_sem(sem_id + 1, 0); // 信号量1初始化为0,表示共享内存是满的
// 生产者进程
while (1) {
P(sem_id); // 等待共享内存为空
// 生产数据并写入共享内存
sprintf(buffer, "Produced Data: %d", rand());
printf("Producer: %s\n", buffer);
V(sem_id + 1); // 标记共享内存为满
}
// 消费者进程
while (1) {
P(sem_id + 1); // 等待共享内存为满
// 从共享内存中取出数据
printf("Consumer: %s\n", buffer);
V(sem_id); // 标记共享内存为空
}
// 注意:在实际使用中,应该有机制能够优雅地终止进程,这里仅为示例。
// 分离共享内存
shmdt(buffer);
// 删除共享内存和信号量
shmctl(shm_id, IPC_RMID, NULL);
semctl(sem_id, 0, IPC_RMID);
return 0;
}
```
请注意,上述代码仅为一个示例,实际应用中需要添加适当的错误处理、同步机制和终止条件。生产者和消费者进程应该分别创建并运行,这里只是为了展示它们如何使用共享内存和信号量进行通信。
阅读全文