• 【Linux 进程间通信】信号量


    API

    int semget(key_t key, int nsems, int semflg);创建或者获取已经存在的信号量
    semget()成功返回信号量的ID,失败返回-1
    key:两个进程使用相同的key值,就可以使用同一个信号量
    nsems:内核维护的是一个信号量集,在新建信号量时,其指定信号量集中信号量的个数
    semflg 可选:IPC_CREAT IPC_EXCL
    IPC_CREAT|IPC_EXCL,如果内核中不存在这样的信号量,则新建,否则,则报错,semfg使用时要与IPC对象权限进行|运算来设定权限
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    int semop(int semid, struct sembuf*sops, unsigned nsops);
    semop(对信号量进行改变,做Р操作或者V操作
    成功返回0,失败返回-1
    struct sembuf{
    unsigned short sem_num;//指定信号量集中的信号量下标
    sem_op;//其值为-1,代表Р操作,其值为1,代表V操作
    short sem_flg;//标志位SEM_UNDO,如果程序执行P操作后,程序奔了,不能执行V操作,SEM_UNDO可以记住程序进行了P操作,就算程序奔溃也可以帮助进行V操作,并不会因为程序奔溃而无法进行V操作,一直阻塞其它进程。
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    int semctl(int semid, int semnum, int cmd,...);控制信号量
    成功返回0,失败返回-1
    cmd选项:SETVAL (赋初值)IPC_RMID(删除)删除时semnum只需要填0就可以了,0只是占参数位置,填0就可以删除所有信号量。
    union semun
     {
     int val;
     struct semid_ds *buf;
    unsigned short *array;
    struct seminfo *_buf;
     }
     此联合体需要用户自己定义
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    案例:交替打印AB

    sem.h

    #include
    #include
    #include
    #include
    #include
    #define NUM 2
    union semun
    {
       int val;
       struct semid_ds * buf;
       unsigned short *array;
       struct seminfo *__buf;
    };
    void sem_init();
    void sem_p(int index);
    void sem_v(int index);
    void sem_destory();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    
    
    • 1

    sem.c

    #include"sem.h"
    #include
    static int semid =-1;
    void sem_init()
    {
        semid = semget((key_t)1234,NUM,IPC_CREAT|IPC_EXCL|0600);
        if(semid == -1)
        {
          semid = semget((key_t)1234,NUM,0600);
          if(semid == -1)
          {
    
              printf("semget erro\n");
          }
        }else//
        {
          union semun a;
          int arr [2]={1,0};
          for(int i=0;i<NUM;++i)
          {
           a.val =arr[i];
          if(semctl(semid,i,SETVAL,a) ==-1)
          {
           printf("semctl init erro\n");
          
          }
         }   
        }
    
    }
    void sem_p(int index)
    {
      if(index <0 || index >=NUM)
      {
       exit(1);
      }
      struct sembuf buf;
      buf.sem_num=index;
      buf.sem_op=-1;
      buf.sem_flg = SEM_UNDO;//yichang zhong duan hou gei xing hao liang v cao zuo
      if(semop(semid,&buf,1) == -1)
      {
      
       printf("semop p erro\n");
      }
    
    }
    void sem_v(int index)
    {
     
      if(index <0 || index >=NUM)
      {
       exit(1);
      }
      struct sembuf buf;
      buf.sem_num=index;
      buf.sem_op=1;
      buf.sem_flg = SEM_UNDO;//yichang zhong duan hou gei xing hao liang v cao zuo
      if(semop(semid,&buf,1) == -1)
      {
      
       printf("semop v  erro\n");
      }
    
    }
    void sem_destory()
    {
      if(semctl(semid,0,IPC_RMID) == -1)      
      {
        printf("semctl destory err\n");
      }
    
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74

    a.c

    #include
    #include
    #include
    #include
    #include"sem.h"
    int main()
    {
      sem_init();  
     for(int i=0;i<5;++i)
     {
      sem_p();
      printf("A");
      fflush(stdout);
      int n = rand()%3;
      sleep(n);
      printf("A");
      fflush(stdout);
      sem_v();
      n = rand()%3;
      sleep(3);
     
     }   
     sleep(10);
     sem_destory();
      exit(0);  
        
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    b.c

    #include
    #include
    #include
    #include
    #include"sem.h"
    int main()
    {
      sem_init();  
     for(int i=0;i<5;++i)
     {
      sem_p();
      printf("B");
      fflush(stdout);
      int n = rand()%3;
      sleep(n);
      printf("B");
      fflush(stdout);
      sem_v();
      n = rand()%3;
      sleep(3);
     
     }   
     sleep(10);
      exit(0);  
        
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    在这里插入图片描述
    ipcs 查看系统的消息队列,共享内存,信号量
    在这里插入图片描述
    0x4d2 为16进制,转换为10进制为1234
    ipcrm -s 信号量id 删除信号量
    在这里插入图片描述

  • 相关阅读:
    黑马C++ 02 核心 4 ——类和对象_C++对象模型和this指针_友元
    极空间变身监控录像机,搭配Onvif摄像头,实现实时观看和录制视频回放功能
    递归——深度优先搜索(DFS)——以滑雪问题为例(自顶而下)
    如何基于three.js(webgl)引擎架构,研发一套通过配置就能自动生成的3D机房系统
    让 Java 打包缩小一大半,Solon v1.9.3 发布
    【已解决】胎教级别FontDetection在本机电脑指导跑通
    搞定实体识别、关系抽取、事件抽取,我用指针网络
    工程水文学试卷
    氨基修饰二硒化钨WSe2纳米粒 (NH2-WSe2)|羧酸聚乙二醇修饰二硒化钨 (COOH-PEG-WSe2)
    记一次服务间调用失败的bug
  • 原文地址:https://blog.csdn.net/aoeaoao/article/details/127943916