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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章