io信号灯


#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;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值