linux编程---信号量通信机制

来源:互联网 发布:linux ftp更改下载目录 编辑:程序博客网 时间:2024/06/05 11:27

信号量通信机制主要用来实现进程间同步,信号量用来标识系统可用资源的个数。


信号量管理操作

1.  创建信号量集合

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

 int semget(key_t key, int nsems, int semflg);


2. 控制信号量集合、信号量

 int semctl(int semid, int semnum, int cmd, ...);


3.  信号量操作

 int semop(int semid, struct sembuf *sops, unsigned nsops);


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

static int semaphore_v(void);
static int set_semvalue(void);
static int get_semvalue(void);

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

int sem_id;

int main(int argc,char* argv[])
{
    pid_t pid;
    int i;
    int value;
    key_t key;
    int status;
    
    if((key = ftok(".",'B')) == -1)
    perror("ftok ");
    
    if((pid = fork()) == -1)
    {
        perror("fork ");
        exit(-1);
    }
    else if(pid == 0)
    {
        if((sem_id = semget(key,1,IPC_CREAT|0777)) == -1)
            perror("semget ");
        if(!set_semvalue())
            fprintf(stderr,"failed to initialize semphore\n");
        value = get_semvalue();
        printf("this is child,the current value is %d\n",value);
        
        if(!semaphore_v())
            fprintf(stderr,"failed to v operator\n");
        value = get_semvalue();
        printf("the child %d V operator,value %d \n",i,value);
        
        printf("child exit sucess\n");
        exit(0);    
    }
    else{
    sleep(3);
    if((sem_id = semget(key,1,IPC_CREAT|0777)) == -1)
        perror("semget ");
    
    value = get_semvalue();
    printf("this is parent,the current value is %d\n",value);
    printf("the parent will remove the sem\n");
    if(semctl(sem_id,0,IPC_RMID,(struct msquid_ds*)0) == -1)
        perror("semctl");
    
    return 0;    
    }    
}

static int set_semvalue(void )
{
    union semun sem_union;
    int value;
    sem_union.val = 5;
    if(semctl(sem_id,0,SETVAL,sem_union) == -1)
        return 0;
    printf("set value success,");
    printf("init value is %d\n",get_semvalue());
}

static int get_semvalue(void)
{
    int res;
    if((res = semctl(sem_id,0,GETVAL)) == -1)
        perror("semctl");
    
    return res;    
}

static int semaphore_v(void)
{
    struct sembuf sem_b;
    sem_b.sem_num = 0;
    //sem_b.sem_op = 1; //V
    sem_b.sem_op = -2;  //P
    //sem_b.sem_flg = 0;
    sem_b.sem_flg = SEM_UNDO;
    if(semop(sem_id,&sem_b,1) == -1)
        perror("semop ");
    return 1;
}


生产者与消费者问题


生产者代码

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

int sem_id;

void init()
{
        key_t key;
        int ret;
        unsigned short sem_array[2];
        union semun
        {
                int val;
                struct semid_ds* buf;
                unsigned short* array;
        }arg;

        key = ftok(".",'s');
        sem_id = semget(key,2,IPC_CREAT|0644);
        sem_array[0] = 0;
        sem_array[1] = 100;
        arg.array = sem_array;
        ret = semctl(sem_id,0,SETALL,arg);
        if(ret == -1)
                perror("semctl ");

        printf("productor init is %d\n",semctl(sem_id,0,GETVAL));
        printf("space init is %d\n",semctl(sem_id,1,GETVAL));
}

void del()
{
        semctl(sem_id,IPC_RMID,0);
}

int main(int argc,char* argv[])
{
        struct sembuf sops[2];
        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;

        init();
        printf("this is productor\n");

        while(1)
        {
                printf("\n\nbefore produce:\n");
                printf("productor number is %d\n",semctl(sem_id,0,GETVAL));
                printf("space number is %d\n",semctl(sem_id,1,GETVAL));
                semop(sem_id,(struct sembuf*)&sops[1],1);
                printf("now producing ...\n");
                semop(sem_id,(struct sembbuf*)&sops[0],1);

                printf("\nafter produce\n");
                printf("productor number is %d\n",semctl(sem_id,0,GETVAL));
                printf("space number is %d\n",semctl(sem_id,1,GETVAL));
                sleep(4);
        }
        del();
}



消费者代码

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

int sem_id;

void init()
{
        key_t key;
        int ret;
        unsigned short sem_array[2];
        union semun
        {
                int val;
                struct semid_ds* buf;
                unsigned short* array;
        }arg;

        key = ftok(".",'s');
        sem_id = semget(key,2,IPC_CREAT|0644);
}

int main(int argc,char* argv[])
{
        init();
        struct sembuf sops[2];
        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;

        //init();
        printf("this is customer\n");

        while(1)
        {
                printf("\n\nbefore consume:\n");
                printf("productor number is %d\n",semctl(sem_id,0,GETVAL));
                printf("space number is %d\n",semctl(sem_id,1,GETVAL));
                semop(sem_id,(struct sembuf*)&sops[0],1);
                printf("now consuming ...\n");
                semop(sem_id,(struct sembbuf*)&sops[1],1);

                printf("\nafter consume\n");
                printf("productor number is %d\n",semctl(sem_id,0,GETVAL));
                printf("space number is %d\n",semctl(sem_id,1,GETVAL));
                sleep(3);
        }
}




原创粉丝点击