zoukankan      html  css  js  c++  java
  • IPC之——信号量集

    信号量集用于对存在竞争的资源加锁

    1.semId=semget(key,nsems,semflg)

      key:为信号量集名称,可以指定为0455等数字,也可以为PC_PRIVATE

      nsems:创建几个信号量

      semflg:创建并给权限,如(IPC_CREAT | 0600);

    2.semctl(semId,semnum,cmd,...)//

      2.1初始化信号量集  

      semctl(semId,num,SETVAL,1)  将semId的第num个信号量设置为1;semvalue

      2.2删除信号量集

      semctl(semId,0,IPC_RMID)    删除信号量集semId

      .......

    3. 锁的操作

      semop(semId,&buf,1)/////能做则做,不能做则阻塞等待

      锁操作是将要操作的信号放到一个结构体中 struct sembuf   buf;

      buf.sem_num:对第几个信号操作

      buf.sem_op:  有三种情况  大于0(释放资源)   小于0(申请资源)     等于0(等0操作)

      buf.sem_flg:  是否阻塞

      semop(semId,&buf,1);操作1个这样的buf

    ·

      semtimeop()//能做则做,不能做则阻塞一段时间后返回,常用于超时等待

    代码示例

    //等零操作:子进程执行10次 父进程执行一次
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/sem.h>
    #include <sys/wait.h>

    #define      NR     1

    int p_lock(int semId);
    void v_unlock(int semId);
    void w_zero(int semId);


    int main(void)
    {
        int semId,ret;
        pid_t pid;

        semId=semget(IPC_PRIVATE,NR,0600);
        if(semId==-1)
        {
            perror("semget");
            return 1;
        }
        //init sem value
        ret=semctl(semId,0,SETVAL,0);
        if(ret==-1)
        {
            perror("set sem val");
            semctl(semId,0,IPC_RMID);
            return 2;
        }

        //create child process  继承semId
        pid=fork();
        if(pid==-1)
        {
            semctl(semId,0,IPC_RMID);
            perror("fork");
            return 3;
        }
        else if(pid==0)//child
        {
            int count=1;
            while(1)
            {
                p_lock(semId);
                printf("child do %dth ",count);
                count++;
                sleep(1);
            }
            exit(0);
        }
        //aprent
        while(1)
        {
            w_zero(semId);
            printf("parent do.... ");

            v_unlock(semId);
        }

        wait(NULL);
     
        semctl(semId,0,IPC_RMID);
        return 0;
    }
    int p_lock(int semId)
    {
        struct sembuf  buf[1];
        buf[0].sem_num=0;//第几个
        buf[0].sem_op =-1;//怎么操作(1.op>0 指释放资源   2.op<0 申请资源  3.op==0等大资源为0)
        buf[0].sem_flg=0; //IPC_NOWAIT

        return semop(semId,buf,1);
    }

    void v_unlock(int semId)
    {
        struct sembuf  buf;
        buf.sem_num=0;//第几个
        buf.sem_op =10;//怎么操作(1.op>0 指释放资源   2.op<0 申请资源  3.op==0等大资源为0)
        buf.sem_flg=0; //IPC_NOWAIT

        semop(semId,&buf,1);
    }
    void w_zero(int semId)
    {
        struct sembuf  buf;
        buf.sem_num=0;//第几个
        buf.sem_op =0;//怎么操作(1.op>0 指释放资源   2.op<0 申请资源  3.op==0等大资源为0)
        buf.sem_flg=0; //IPC_NOWAIT

        semop(semId,&buf,1);

    }

  • 相关阅读:
    Ubuntu下的OpenResty 安装
    你真的理解devDependencies和dependencies区别吗?
    "No user exists for uid 501"
    Mongo的备份和恢复(mongodump 和mongorestore )
    mongodb最大连接数、最大连接数修改
    ssh 断开解决办法
    Know How To Use Check Box Mapping Of Other Values Property In Oracle Forms
    Date Picker Calendar For Oracle Forms 6i
    Freebie: Date Picker Calendar Demo Form For Oracle Forms 6i
    Creating Excel File in Oracle Forms
  • 原文地址:https://www.cnblogs.com/edan/p/8906246.html
Copyright © 2011-2022 走看看