#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
union semun {
int val; // 信号量的值
struct semid_ds *buf; // 信号量集的描述符
unsigned short *array; // 信号量数组
};
// 初始化信号量
void init(int semid, int num, int val) {
union semun sem;
sem.val = val;
if (semctl(semid, num, SETVAL, sem) == -1) {
perror("semctl SETVAL 错误");
_exit(1);
}
}
// 执行 P 或 V 操作
void pv(int semid, int num, int op) {
struct sembuf buf;
buf.sem_num = num; // 信号量编号
buf.sem_op = op; // 操作类型:-1 为 P 操作,1 为 V 操作
buf.sem_flg = 0; // 操作标志
if (semop(semid, &buf, 1) == -1) {
perror("semop 错误");
_exit(1);
}
}
int main(int argc, char const *argv[]) {
key_t key;
int semid, shmid;
char *shm;
// 生成键值
if ((key = ftok("sem.c", 'a')) < 0) {
perror("ftok 错误");
return -1;
}
printf("key: %#x\n", key);
// 创建或获取信号量集
if ((semid = semget(key, 2, IPC_CREAT | 0666)) == -1) {
perror("semget 错误");
return -1;
}
// 如果信号量集是新创建的,则初始化信号量
if (semctl(semid, 0, GETVAL) == -1) {
if (errno == ENOENT) {
// 信号量集不存在,初始化信号量
init(semid, 0, 1); // 互斥信号量
init(semid, 1, 0); // 空信号量
} else {
perror("semctl GETVAL 错误");
return -1;
}
}
printf("semid: %d\n", semid);
// 创建或获取共享内存
if ((shmid = shmget(key, 1024, IPC_CREAT | 0666)) == -1) {
perror("shmget 错误");
return -1;
}
// 附加共享内存
if ((shm = (char *)shmat(shmid, NULL, 0)) == (char *)-1) {
perror("shmat 错误");
return -1;
}
// 输入输出循环
char input[100];
while (1) {
printf("请输入消息(输入 'quit' 退出):");
fgets(input, sizeof(input), stdin);
if (strncmp(input, "quit", 4) == 0) break;
// 执行信号量操作
pv(semid, 0, -1); // 对互斥信号量执行 P 操作
strcpy(shm, input); // 写入共享内存
pv(semid, 1, 1); // 对空信号量执行 V 操作
printf("消息已写入共享内存:%s", shm);
}
// 分离和清理
if (shmdt(shm) == -1) {
perror("shmdt 错误");
return -1;
}
if (shmctl(shmid, IPC_RMID, NULL) == -1) {
perror("shmctl IPC_RMID 错误");
return -1;
}
if (semctl(semid, 0, IPC_RMID) == -1) {
perror("semctl IPC_RMID 错误");
return -1;
}
return 0;
}
io信号灯
最新推荐文章于 2024-09-03 20:45:39 发布