嵌入式2020——信号量集例程

csem.c

#include <stdio.h>
#include <errno.h>
#include <sys/sem.h>
int pmenu(void) {
    printf("--------------------\n");
    printf("    迷你图书馆\n");
    printf("--------------------\n");
    printf("[1] 借《三国演义》\n");
    printf("[2] 还《三国演义》\n");
    printf("[3] 借《水浒传》\n");
    printf("[4] 还《水浒传》\n");
    printf("[5] 借《红楼梦》\n");
    printf("[6] 还《红楼梦》\n");
    printf("[7] 借《西游记》\n");
    printf("[8] 还《西游记》\n");
    printf("[0] 退出\n");
    printf("--------------------\n");
    printf("请选择:");
    int sel = -1;
    scanf("%d", &sel);
    return sel;
}
int pleft(int semid, unsigned short semnum) {
    int val = semctl(semid, semnum, GETVAL);
    if (val == -1) {
        perror("semctl");
        return -1;
    }
    printf("还剩%d册。\n", val);
    return 0;
}
int borrow(int semid, unsigned short semnum) {
    struct sembuf sops = {
        semnum, -1, /*0*/IPC_NOWAIT};
    if (semop(semid, &sops, 1) == -1) {
        if (errno != EAGAIN) {
            perror("semop");
            return -1;
        }
        printf("暂时无书,下回再试。\n");
        return 0;
    }
    printf("恭喜恭喜,借阅成功。\n");
    return pleft(semid, semnum);
}
int revert(int semid, unsigned short semnum) {
    struct sembuf sops = {semnum, 1, 0};
    if (semop(semid, &sops, 1) == -1) {
        perror("semop");
        return -1;
    }
    printf("好借好还,再借不难。\n");
    return pleft(semid, semnum);
}
int main(void) {
    printf("创建信号量集...\n");
    key_t key = ftok(".", 100);
    if (key == -1) {
        perror("ftok");
        return -1;
    }
    int semid = semget(key, 4, 0644 | IPC_CREAT |
        IPC_EXCL);
    if (semid == -1) {
        perror("semget");
        return -1;
    }
    printf("初始化信号量...\n");
    unsigned short semarr[] = {5, 5, 5, 5};
    if (semctl(semid, 0, SETALL, semarr) == -1) {
        perror("semctl");
        return -1;
    }
    int quit = 0;
    while (!quit) {
        int sel = pmenu();
        switch (sel) {
            case 0:
                quit = 1;
                break;
            case 1: // 借《三国演义》-> 0
            case 3: // 借《水浒传》  -> 1
            case 5: // 借《红楼梦》  -> 2
            case 7: // 借《西游记》  -> 3
                if (borrow(semid, sel / 2) == -1)
                    return -1;
                break;
            case 2: // 还《三国演义》-> 0
            case 4: // 还《水浒传》  -> 1
            case 6: // 还《红楼梦》  -> 2
            case 8: // 还《西游记》  -> 3
                if (revert(semid,
                    (sel - 1) / 2) == -1)
                    return -1;
                break;
            default:
                printf("无效选择!\n");
                scanf("%*[^\n]");
                scanf("%*c");
                break;
        }
    }
    printf("销毁信号量集...\n");
    if (semctl(semid, 0, IPC_RMID) == -1) {
        perror("semctl");
        return -1;
    }
    printf("完成!\n");
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值