1.24 共享内存和信号灯集
使用共享内存+信号灯集实现两个进程之间相互对话。
程序代码:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stst.h>
#include <fcntl.h>
#include <pthread.h>
#include <semaphore.h>
#include <wait.h>
#include <signal.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <semaphore.h>
#include <sys/sem.h>
#include <sys/un.h>
#define SHM_SIZE 1024
#define KEY 1234
#define SEM_KEY 5678
// 信号灯操作函数
void sem_op(int semid, int num, int op) {
struct sembuf sb;
sb.sem_num = num;
sb.sem_op = op;
sb.sem_flg = 0;
if (semop(semid, &sb, 1) == -1) {
perror("semop");
exit(EXIT_FAILURE);
}
}
// 发送进程
void sender() {
int shmid, semid;
char *shmaddr;
// 创建共享内存
if ((shmid = shmget(KEY, SHM_SIZE, IPC_CREAT | 0666)) == -1) {
perror("shmget");
exit(EXIT_FAILURE);
}
// 附加共享内存
if ((shmaddr = shmat(shmid, NULL, 0)) == (void *)-1) {
perror("shmat");
exit(EXIT_FAILURE);
}
// 创建信号灯集
if ((semid = semget(SEM_KEY, 2, IPC_CREAT | 0666)) == -1) {
perror("semget");
exit(EXIT_FAILURE);
}
// 初始化信号灯
if (semctl(semid, 0, SETVAL, 1) == -1) {
perror("semctl");
exit(EXIT_FAILURE);
}
if (semctl(semid, 1, SETVAL, 0) == -1) {
perror("semctl");
exit(EXIT_FAILURE);
}
char message[SHM_SIZE];
while (1) {
// 等待可以发送消息
sem_op(semid, 0, -1);
printf("Sender: ");
fgets(message, SHM_SIZE, stdin);
if (strncmp(message, "quit", 4) == 0) {
strcpy(shmaddr, "quit");
sem_op(semid, 1, 1);
break;
}
strcpy(shmaddr, message);
// 通知接收进程有新消息
sem_op(semid, 1, 1);
}
// 分离共享内存
if (shmdt(shmaddr) == -1) {
perror("shmdt");
exit(EXIT_FAILURE);
}
}
// 接收进程
void receiver() {
int shmid, semid;
char *shmaddr;
// 获取共享内存
if ((shmid = shmget(KEY, SHM_SIZE, 0666)) == -1) {
perror("shmget");
exit(EXIT_FAILURE);
}
// 附加共享内存
if ((shmaddr = shmat(shmid, NULL, 0)) == (void *)-1) {
perror("shmat");
exit(EXIT_FAILURE);
}
// 获取信号灯集
if ((semid = semget(SEM_KEY, 2, 0666)) == -1) {
perror("semget");
exit(EXIT_FAILURE);
}
while (1) {
// 等待有新消息
sem_op(semid, 1, -1);
if (strncmp(shmaddr, "quit", 4) == 0) {
break;
}
printf("Receiver: %s", shmaddr);
// 通知发送进程可以继续发送
sem_op(semid, 0, 1);
}
// 分离共享内存
if (shmdt(shmaddr) == -1) {
perror("shmdt");
exit(EXIT_FAILURE);
}
// 删除共享内存和信号灯集
if (shmctl(shmid, IPC_RMID, NULL) == -1) {
perror("shmctl");
exit(EXIT_FAILURE);
}
if (semctl(semid, 0, IPC_RMID) == -1) {
perror("semctl");
exit(EXIT_FAILURE);
}
}
int main() {
pid_t pid;
// 创建子进程
pid = fork();
if (pid == -1) {
perror("fork");
exit(EXIT_FAILURE);
} else if (pid == 0) {
// 子进程作为接收进程
receiver();
} else {
// 父进程作为发送进程
sender();
}
return 0;
}