歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Linux system V IPC 信號燈和共享內存實例

Linux system V IPC 信號燈和共享內存實例:

#include<sys/types.h>
#include<linux/sem.h>
#include<linux/shm.h>
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<time.h>


#define MAXSHM 5  //定義緩沖區數組的下標變量個數

/*        定義3個信號量的內部標識  */

int fullid;
int emptyid;
int mutexid;

/* 主函數  */

int main()
{
/*  定義2個共享內存的ID  */

    int arrayid;
    int getid;

    /*  定義共享內存虛擬地址  */

    int *array;
    int *get;

    /* 創建共享內存  */
   
    arrayid=shmget(IPC_PRIVATE,sizeof(int) * MAXSHM,IPC_CREAT|0666);
    getid=shmget(IPC_PRIVATE,sizeof(int),IPC_CREAT|0666);
   
    /*  初始化共享內存  */
   
    array=(int *) shmat(arrayid,0,0);
    get=(int *) shmat(getid,0,0);
   
    *get=0;

    /* 定義信號量數據結構 */

    struct sembuf  P,V;
    union semun arg;

    /* 創建信號量  */

    fullid=semget(IPC_PRIVATE,1,IPC_CREAT|0666);
    emptyid=semget(IPC_PRIVATE,1,IPC_CREAT|0666);
    mutexid=semget(IPC_PRIVATE,1,IPC_CREAT|0666);

    /*初始化信號量 */
   
    arg.val=0;            //初始時緩沖區中無數據

    if(semctl(fullid,0,SETVAL,arg)==-1)
    {
        perror("semctl setval error");
    }

    arg.val=MAXSHM;       //初始時緩沖區中有5個空閒的數組元素

    if(semctl(emptyid,0,SETVAL,arg)==-1)
    {
        perror("semctl setval error");
    }

    arg.val=1;            //初始時互斥信號為1,允許一個進程進入

    if(semctl(mutexid,0,SETVAL,arg)==-1)
    {
        perror("semctl setval error");
    }

    /* 初始化 P  V操作  */

    P.sem_num=0;
    P.sem_op=-1;
    P.sem_flg=SEM_UNDO;
   
    V.sem_num=0;
    V.sem_op=1;
    V.sem_flg=SEM_UNDO;

    /*   生產者進程  */

    if(fork()==0)
    {
        int i=0;
        int set=0;

        while(i<10)
        {
            semop(emptyid,&P,1);         //對 emptyid執行P操作
            semop(mutexid,&P,1);         //對 mutexid執行 P操作
           
            array[set%MAXSHM]=i+1;
           
            printf("Producer put number %d to No.%d\n",array[set%MAXSHM],set%MAXSHM);

            set++;                       //寫計數加1

            semop(mutexid,&V,1);         //對mutexid執行 V 操作
            semop(fullid,&V,1);          //對fullid執行 V 操作

            i++;
        }

        sleep(3);                    //SLEEP 3秒,等待消費者進程執行完畢
        printf("Poducer if over\n");
        exit(0);
    }
    else
    {
        /*  消費者A進程  */
        if(fork()==0)
        {
            while(1)
            {
                if(*get==10)
                {
                    break;
                }
               
                semop(fullid,&P,1);        //對fullid執行 P 操作
                semop(mutexid,&P,1);       //對mutexid執行 P 操作

                printf("The ConsumerA get number from No.%d\n",(*get)%MAXSHM);
               
                (*get)++;                   //讀計數加1

                semop(mutexid,&V,1);        //對mutexid執行 V 操作
                semop(emptyid,&V,1);        //對fullid執行 V 操作

                sleep(1);
            }
           
            printf("ConsunerA is over\n");
            exit(0);
        }
        else
        {
            /*消費者B進程  */
            if(fork()==0)
            {
                while(1)
                {
                    if(*get==10)
                    {
                        break;
                    }

                    semop(fullid,&P,1);       //對fullid執行 P 操作
                    semop(mutexid,&P,1);      //對mutexid執行 P 操作

                    printf("The ConsumerB get number from No.%d\n",(*get)%MAXSHM);

                    (*get)++;                 //讀計數加1

                    semop(mutexid,&V,1);      //對mutexid執行 V 操作
                    semop(emptyid,&V,1);      //對emptyid執行 V 操作
                   
                    sleep(1);
                }
               
                printf("ConsunerB is over\n");
                exit(0);
            }
        }
    }

    /*   父進程返回後回收3個子進程  */
   
    wait(0);
    wait(0);
    wait(0);

    /*  斷開並撤消2個共享內存  */

    shmdt(array);
    shmctl(arrayid,IPC_RMID,0);
    shmctl(get);
    shmctl(getid,IPC_RMID,0);
   
    /*   撤消3個信號量集  */

    semctl(emptyid,IPC_RMID,0);
    semctl(fullid,IPC_RMID,0);
    semctl(mutexid,IPC_RMID,0);

    exit(0);
}

Copyright © Linux教程網 All Rights Reserved