利用信息量集实现互斥访问
进程A
用来生成信号集,并将其初值设为1(运行顺序为进程A->B->C)
/*
* @Author: Eon eon4051@163.com
* @Date: 2024-05-08 17:20:41
* @LastEditors: Eon eon4051@163.com
* @LastEditTime: 2024-05-28 18:47:38
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <error.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
union semun
{
int val; /* value for SETVAL */
struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* array for GETALL, SETALL */
struct seminfo *__buf; /* buffer for IPC_INFO */
};
int main()
{
union semun arg;
// 创建信号量集
int sem_id = semget(ftok("./mysem", 20), 1, 0664 | IPC_CREAT | IPC_EXCL);
if (sem_id == -1)
{
fprintf(stderr, "semid open is false,errno:%d,%s\n", errno, strerror(errno));
sem_id = semget(ftok("./mysem", 20), 1, 0664);
}
//设置信号量集的初始值为1
arg.val = 1;
semctl(sem_id, 0, SETVAL, arg);
//int ret = semctl(sem_id, 0, GETVAL, arg);
//printf("sem[0]=%d", ret);
// 将共享空间内初值设为1
int shm_id = shmget(ftok("./myshm", 21), 4, 0666 | IPC_CREAT);
int *a = (int *)shmat(shm_id, NULL, 0);
*a = 1;
shmdt(a);
//printf("sem_id=%d\n", sem_id);
//printf("shm_id=%d\n", shm_id);
while (1)
{
sleep(1);
}
return 0;
}
进程B
用来对共享内存内的int值进行修改,每秒+1
/*
* @Author: Eon eon4051@163.com
* @Date: 2024-05-08 17:20:41
* @LastEditors: Eon eon4051@163.com
* @LastEditTime: 2024-05-28 18:29:25
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <error.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
// struct sembuf
// {
// unsigned short sem_num;
// short sem_op;
// short sem_flg;
// };
/***对信号量数组semnum编号的信号量做P操作(申请)***/
int P(int semid, int semnum)
{
struct sembuf sops = {semnum, -1, SEM_UNDO};
return (semop(semid, &sops, 1));
}
/***对信号量数组semnum编号的信号量做V操作(释放)***/
int V(int semid, int semnum)
{
struct sembuf sops = {semnum, +1, 0};
return (semop(semid, &sops, 1));
}
int main()
{
// b端修改共享内存内的值
int sem_id = semget(ftok("./mysem", 20), 1, 0664 | IPC_CREAT | IPC_EXCL);
if (sem_id == -1)
{
fprintf(stderr, "semid open is false,errno:%d,%s\n", errno, strerror(errno));
sem_id = semget(ftok("./mysem", 20), 1, 0664);
}
int shm_id = shmget(ftok("./myshm", 21), 4, 0666 | IPC_CREAT);
//printf("sem_id=%d\n", sem_id);
//printf("shm_id=%d\n", shm_id);
while (1)
{
P(sem_id, 0);
int *a = (int *)shmat(shm_id, NULL, 0);
//int temp = (*a) + 1;
//printf("输入为%d\n", temp);
*a = (*a) + 1;
shmdt(a);
sleep(1);
V(sem_id, 0);
}
return 0;
}
进程C
用来读取共享内存内的数据并将其在命令行终端输出
/*
* @Author: Eon eon4051@163.com
* @Date: 2024-05-08 17:20:41
* @LastEditors: Eon eon4051@163.com
* @LastEditTime: 2024-05-28 18:49:55
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <error.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
// struct sembuf
// {
// unsigned short sem_num;
// short sem_op;
// short sem_flg;
// };
/***对信号量数组semnum编号的信号量做P操作(申请)***/
int P(int semid, int semnum)
{
struct sembuf sops = {semnum, -1, SEM_UNDO};
return (semop(semid, &sops, 1));
}
/***对信号量数组semnum编号的信号量做V操作(释放)***/
int V(int semid, int semnum)
{
struct sembuf sops = {semnum, +1, 0};
return (semop(semid, &sops, 1));
}
int main()
{
// C端输出共享内存内的值
int sem_id = semget(ftok("./mysem", 20), 1, 0664 | IPC_CREAT | IPC_EXCL);
if (sem_id == -1)
{
fprintf(stderr, "semid open is false,errno:%d,%s\n", errno, strerror(errno));
sem_id = semget(ftok("./mysem", 20), 1, 0664);
}
int shm_id = shmget(ftok("./myshm", 21), 4, 0666 | IPC_CREAT);
//printf("sem_id=%d\n", sem_id);
//printf("shm_id=%d\n", shm_id);
while (1)
{
P(sem_id, 0);
int *a = (int *)shmat(shm_id, NULL, 0);
printf("共享内存内的值为:%d\n", a[0]);
shmdt(a);
sleep(1);
V(sem_id, 0);
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异