IPC-信号灯

IPC-信号灯之生产者消费者


有亲缘关系生产者消费者

子进程生成,父进程消费

#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<stdlib.h>

union semun
{
    int val;
    struct semid_ds *buf;
    unsigned short *array;
    struct seminfo *__buf;
};

int main(void)
{
    int semid = semget(0, 1, 0666|IPC_CREAT);// 0为IPC_PRIVATE表示该信号灯集在父子进程间,1表示信号灯集有1个信号灯
    if(-1 == semid)
    {
        perror("semget");
        exit(EXIT_FAILURE);
    }

    union semun sm;
    sm.val = 5;     // sm.val表示某个信号灯的起始资源数量
    if(-1 == semctl(semid, 0, SETVAL, sm))  // 将sm写到下标为0的信号灯(semid所标识的信号灯集)中
    {
        perror("semctl");
        exit(EXIT_FAILURE);
    }

    if(fork() == 0) // 子进程为生产者
    {
        struct sembuf sop;
        sop.sem_num = 0;    // 下标为0的信号灯
        sop.sem_op = 1;     // V操作
        sop.sem_flg = 0;    // 0代表资源不足则阻塞
        while(1)
        {
            sleep(3);
            if(-1 == semop(semid, &sop, 1)) // 1表示sembuf数组(sop)大小为1
            {
                perror("semop");
                exit(EXIT_FAILURE);
            }
            printf("V  资源数量:%d\n", semctl(semid, 0, GETVAL, sm));
        }
        return 0;
    }
    // 消费者
    struct sembuf sop;
    sop.sem_num = 0;
    sop.sem_op = -1;
    sop.sem_flg = 0;

    while(1)
    {
        if(-1 == semop(semid, &sop, 1))
        {
            perror("semop");
            exit(EXIT_FAILURE);
        }
        printf("P  资源数量:%d\n", semctl(semid, 0, GETVAL));
        sleep(1);
    }
    return 0;
}

无亲缘关系

问题描述:一个仓库能装下10个产品。仓库装满之后,生产者停止生产,等待仓库非满;仓库空之后,消费者停止消费,等待仓库非空

producer.c

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/sem.h>
#include<sys/ipc.h>

//生产者消费者之间设置相同且唯一的KEY,以便获取相同的semid,最好用ftok获取,以便保证唯一性
#define KEY 1234

union semun
{
    int val;
    struct semid_ds *buf;
    unsigned short *array;
    struct seminfo *__buf;
};

int createSemSet(int nsems, int semflg)
{
    int semid;
    semid = semget(KEY, nsems, semflg);
    if(-1 == semid)
    {
        perror("semget");
        exit(EXIT_FAILURE);
    }
    return semid;
}

int semctlSetall(int semid)
{
    unsigned short arr[2];
    arr[0] = 0;     // 仓库初始库存
    arr[1] = 10;    // 仓库剩余空间
    union semun sm;
    sm.array = arr;
    int returnValue = semctl(semid, 0, SETALL, sm);
    if(-1 == returnValue)
    {
        perror("semctl SETALL");
        exit(EXIT_FAILURE);
    }
    return returnValue;
}

void init2Sembuf(struct sembuf *sops)
{
    sops[0].sem_num = 0;
    sops[0].sem_op = 1; // V操作
    sops[0].sem_flg = 0;// 资源不足则阻塞
    sops[1].sem_num = 1;
    sops[1].sem_op = -1;// P操作
    sops[1].sem_flg = 0;
}

int main(void)
{
    int semid;
    semid = createSemSet(2, IPC_CREAT|0666);
    semctlSetall(semid);
    struct sembuf sops[2];
    init2Sembuf(sops);
    while(1)
    {
        printf("--productor number is %d, space number is %d\n", semctl(semid, 0, GETVAL), semctl(semid, 1, GETVAL));
        sleep(2);
        if(-1 == semop(semid, sops, 2))
        {
            perror("semop");
            exit(EXIT_FAILURE);
        }
        printf("productor number is %d, space number is %d\n", semctl(semid, 0, GETVAL), semctl(semid, 1, GETVAL));
    }
    return 0;
}

customer.c

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/sem.h>
#include<sys/ipc.h>

#define KEY 1234

int createSemSet(int nsems, int semflg)
{
    int semid;
    semid = semget(KEY, nsems, semflg);
    if(-1 == semid)
    {
        perror("semget");
        exit(EXIT_FAILURE);
    }
    return semid;
}

void init2Sembuf(struct sembuf *sops)
{
    sops[0].sem_num = 0;
    sops[0].sem_op = -1;
    sops[0].sem_flg = 0;
    sops[1].sem_num = 1;
    sops[1].sem_op = 1;
    sops[1].sem_flg = 0;
}

int main(void)
{
    int semid;
    semid = createSemSet(2, IPC_CREAT|0666);
    struct sembuf sops[2];
    init2Sembuf(sops);
    while(1)
    {
        printf("--productor number is %d, space number is %d\n", semctl(semid, 0, GETVAL), semctl(semid, 1, GETVAL));
        sleep(1);
        if(-1 == semop(semid, sops, 2))
        {
            perror("semop");
            exit(EXIT_FAILURE);
        }
        printf("productor number is %d, space number is %d\n", semctl(semid, 0, GETVAL), semctl(semid, 1, GETVAL));
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章