利用信息量集实现互斥访问

进程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;
}
posted @   藍桉未遇釋槐鳥  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
点击右上角即可分享
微信分享提示