Linux IPC解析:匿名命名管道与共享内存
warning:
这篇文章距离上次修改已过190天,其中的内容可能已经有所变动。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
// 信号量操作函数
int p(int semid, int semnum) {
struct sembuf sem_b = {semnum, -1, 0}; // 减1操作
return semop(semid, &sem_b, 1);
}
int v(int semid, int semnum) {
struct sembuf sem_b = {semnum, 1, 0}; // 加1操作
return semop(semid, &sem_b, 1);
}
int main() {
key_t key = ftok("shmfile", 65); // 创建key
int shmid = shmget(key, 1024, 0644 | IPC_CREAT); // 创建共享内存
char *shmadd = (char *)shmat(shmid, NULL, 0); // 附加共享内存
key_t semkey = ftok("semfile", 65); // 创建信号量key
int semid = semget(semkey, 1, 0666 | IPC_CREAT); // 创建信号量集合
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
} arg;
arg.val = 1; // 信号量初值设为1
semctl(semid, 0, SETVAL, arg); // 初始化信号量
// 生产者代码
if (fork() == 0) {
while(1) {
p(semid, 0); // P操作
printf("Input string:\n");
fgets(shmadd, 1024, stdin);
if(!strncasecmp(shmadd, "exit", 4)) {
break;
}
v(semid, 0); // V操作
}
exit(0);
}
// 消费者代码
if (fork() == 0) {
while(1) {
p(semid, 0); // P操作
if(!strncasecmp(shmadd, "exit", 4)) {
v(semid, 0); // 如果是退出信号,则需要还原信号量
break;
} else {
printf("Consumer get: %s", shmadd);
}
v(semid, 0); // V操作
}
exit(0);
}
wait(NULL); // 等待子进程结束
wait(NULL);
shmctl(shmid, IPC_RMID, NULL); // 删除共享内存
semctl(semid, 0, IPC_RMID); // 删除信号量
return 0;
}
这段代码使用了匿名命名管道和共享内存来实现一个简单的生产者-消费者模型。它创建了一个共享内存区域,用于生产者和消费者之间的文本传递,并使用信号量来控制对共享内存的访问。代码中包含了信号量的PV操作,以及共享内存的创建、附加和删除操作。最后,代码中还包含了进程管理,如创建子进程、等待子进程结束等。
评论已关闭