• 【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 删除信号量
    在这里插入图片描述

  • 相关阅读:
    单片机设计_RTC时钟(ACM32F403)
    构建强大的RESTful API:@RestController与@Controller的对比与应用
    java计算机毕业设计科学评价系统源码+数据库+系统+lw文档+mybatis+运行部署
    电子商务商城源码 Spring Cloud、Spring Boot、Mybatis、Redis
    Mathematics-Vocabulary·数学专业英语词汇
    36 - 新的 Promise 方法:allSettled & any & race
    【爬虫进阶】猿人学任务一之JS混淆(难度2.0)
    行测-图形推理-7-相异图形类
    欧拉路,欧拉回路
    基于大语言模型(LLM)的合成数据生成、策展和评估的综述
  • 原文地址:https://blog.csdn.net/aoeaoao/article/details/127943916