#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/shm.h>
#include <string.h>
#include <sys/wait.h>
union semun
{
int val;
struct semid_ds *buf;
unsigned short *array;
};
int init_sem(int sem_id, int init_value)
{
union semun sem_union;
sem_union.val = init_value;
if (semctl(sem_id, 0, SETVAL, sem_union) == -1)
{
perror("Initialize semaphore");
return -1;
}
return 0;
}
int main(int argc, char const *argv[])
{
int sem_id = semget(ftok("./mysem", 1), 1, 0666 | IPC_CREAT);
if (sem_id == -1)
{
perror("Create semaphore set");
return -1;
}
if (init_sem(sem_id, 1) == -1)
{
return -1;
}
int shm_id = shmget(ftok("./myshm", 1), sizeof(int), 0666 | IPC_CREAT);
if (shm_id == -1)
{
perror("Create shared memory");
return -1;
}
int *shmaddr = (int *)shmat(shm_id, NULL, 0);
if (shmaddr == (int *)-1)
{
perror("Attach shared memory");
return -1;
}
*shmaddr = 0;
pid_t pid_b = fork();
if (pid_b == 0)
{
struct sembuf sem_op;
while (1)
{
sem_op.sem_num = 0;
sem_op.sem_op = -1;
sem_op.sem_flg = SEM_UNDO;
if (semop(sem_id, &sem_op, 1) == -1)
{
perror("semop wait");
exit(1);
}
(*shmaddr)++;
printf("Process B: a = %d\n", *shmaddr);
printf("Process B is accessing shared memory\n");
sleep(1);
sem_op.sem_num = 0;
sem_op.sem_op = 1;
sem_op.sem_flg = SEM_UNDO;
if (semop(sem_id, &sem_op, 1) == -1)
{
perror("semop signal");
exit(1);
}
sleep(1);
}
exit(0);
}
else if (pid_b < 0)
{
perror("fork");
return -1;
}
sleep(2);
pid_t pid_c = fork();
if (pid_c == 0)
{
struct sembuf sem_op;
while (1)
{
sem_op.sem_num = 0;
sem_op.sem_op = -1;
sem_op.sem_flg = SEM_UNDO;
if (semop(sem_id, &sem_op, 1) == -1)
{
perror("semop wait");
exit(1);
}
printf("Process C: a = %d\n", *shmaddr);
printf("Process C is accessing shared memory\n");
sleep(1);
sem_op.sem_num = 0;
sem_op.sem_op = 1;
sem_op.sem_flg = SEM_UNDO;
if (semop(sem_id, &sem_op, 1) == -1)
{
perror("semop signal");
exit(1);
}
sleep(1);
}
exit(0);
}
else if (pid_c < 0)
{
perror("fork");
return -1;
}
waitpid(pid_b, NULL, 0);
waitpid(pid_c, NULL, 0);
if (shmdt(shmaddr) == -1)
{
perror("shmdt error");
exit(-1);
}
shmctl(shm_id, IPC_RMID, 0);
semctl(sem_id, 0, IPC_RMID);
return 0;
}
void process_task(int sem_id, int *shmaddr, const char *process_name)
{
struct sembuf sem_op;
while (1)
{
sem_op.sem_num = 0;
sem_op.sem_op = -1;
sem_op.sem_flg = SEM_UNDO;
if (semop(sem_id, &sem_op, 1) == -1)
{
perror("semop wait");
exit(1);
}
if (strcmp(process_name, "Process B") == 0)
{
(*shmaddr)++;
printf("%s: a = %d\n", process_name, *shmaddr);
}
printf(" 进程 %s \n", process_name);
sleep(1);
sem_op.sem_num = 0;
sem_op.sem_op = 1;
sem_op.sem_flg = SEM_UNDO;
if (semop(sem_id, &sem_op, 1) == -1)
{
perror("semop signal");
exit(1);
}
sleep(1);
}
}
int main(int argc, char const *argv[])
{
int sem_id = semget(ftok("./mysem", 1), 1, 0666 | IPC_CREAT);
if (sem_id == -1)
{
perror("Create semaphore set");
return -1;
}
if (init_sem(sem_id, 1) == -1)
{
return -1;
}
int shm_id = shmget(ftok("./myshm", 1), sizeof(int), 0666 | IPC_CREAT);
if (shm_id == -1)
{
perror("Create shared memory");
return -1;
}
int *shmaddr = (int *)shmat(shm_id, NULL, 0);
if (shmaddr == (int *)-1)
{
perror("Attach shared memory");
return -1;
}
*shmaddr = 0;
pid_t pid_b = fork();
if (pid_b == 0)
{
process_task(sem_id, shmaddr, "Process B");
exit(0);
}
else if (pid_b < 0)
{
perror("fork");
return -1;
}
pid_t pid_c = fork();
if (pid_c == 0)
{
process_task(sem_id, shmaddr, "Process C");
printf("进程C中数值不变 %d\n", *shmaddr);
exit(0);
}
else if (pid_c < 0)
{
perror("fork");
return -1;
}
waitpid(pid_b, NULL, 0);
waitpid(pid_c, NULL, 0);
if (shmdt(shmaddr) == -1)
{
perror("shmdt error");
exit(-1);
}
shmctl(shm_id, IPC_RMID, 0);
semctl(sem_id, 0, IPC_RMID);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· Qt个人项目总结 —— MySQL数据库查询与断言