• linux IPC的信号量


    信号量相关函数原型

    获得一个信号量ID

    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/sem.h>
    
    int semget(key_t key, int nsems, int semflg);
    返回值:成功信号量ID,出错-1
    key:函数ftok返回值或IPC_PRIVATE(适合用在有亲缘关系的进程中)
    nsems:新的信号量集合中要创建的信号量个数,如果不是新创建的为0
    semflg:  0取信号量集标识符,若不存在则函数会报错
          IPC_CREAT:当semflg&IPC_CREAT为真时,如果不存在与key值相等的信号量集,则创建。否则返回此信号量集的标识符。
          IPC_CREAT|IPC_EXCL:如果不存在与key值相等的信号量集,则创建。否则存在这样的信号集报错

    对信号量的多种操作

    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/sem.h>
    
    int semctl(int semid, int semnum, int cmd, ...);
    除了GETALL以外的所有命令,成功0失败-1
    semid:信号量标识符
    semnum:信号量集数组上的下标,表示某个信号量
    cmd:下面有说明
    arg:semnum联合体
    union semun {
                   int              val;    /* Value for SETVAL */
                   struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
                   unsigned short  *array;  /* Array for GETALL, SETALL */
                   struct seminfo  *__buf;  /* Buffer for IPC_INFO
                                               (Linux-specific) */
               };
    union semun
    struct semid_ds {
                   struct ipc_perm sem_perm;  /* Ownership and permissions */
                   time_t          sem_otime; /* Last semop time */
                   time_t          sem_ctime; /* Last change time */
                   unsigned long   sem_nsems; /* No. of semaphores in set */
               };
    struct semid_ds
    下列10种命令
    IPC_STAT        对此集合取semid_ds结构,并存储在arg.buf指向的结构中 
    IPC_SET          设置一个信号量集合的semid_ds结构中ipc_perm域的值,并从semun的buf中取出值
    IPC_RMID       从内核中删除信号量集合  
    GETALL           从信号量集合中获取所有信号量的值,并存到semun中的指针数组
    GETNCNT        返回当前等待100%自远离用的进程个数
    GETPID          返回最后执行semop的进程PID
    GETVAL          返回信号量集合内单个信号量的值
    GETZCNT         返回当前等待100%资源利用的进程个数
    SETALL            与GETALL正好相反
    SETVAL            用联合体中val成员设置信号量集合中单个信号的值
    cmd指令

    自动执行信号量集合上的操作数组

    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/sem.h>
    
    int semop(int semid, struct sembuf *sops, size_t nsops);
    返回值:成功0出错-1
    semid:信号量标识符
    sops:是指向结构体数组的指针
    nsops:操作结构体的数量,恒大于或等于1

    sembuf结构体

    struct sembuf {
               unsigned short sem_num;  /* semaphore number */
               short          sem_op;   /* semaphore operation */
               short          sem_flg;  /* operation flags */
    }
    struct sembuf

    测试代码:

      1 #include <stdio.h>
      2 #include <sys/types.h>
      3 #include <sys/ipc.h>
      4 #include <sys/sem.h>
      5 
      6 int semid = 0;
      7 
      8 union semun {
      9     int val;
     10     struct semid_ds *buf;
     11     unsigned short *arry;
     12 };
     13 
     14 int set_semvalue()
     15 {
     16     union semun sem_union;
     17 
     18     sem_union.val = 1;
     19     if(semctl(semid, 0, SETVAL, sem_union) == -1)
     20         return -1;
     21 
     22     return 0;
     23 }
     24 
     25 void del_semvalue()
     26 {
     27     union semun sem_union;
     28 
     29     if(semctl(semid, 0, IPC_RMID, sem_union) == -1)
     30         fprintf(stderr, "Failed to delete semaphore
    ");
     31 }
     32 
     33 int P()
     34 {
     35     struct sembuf sem_b;
     36     sem_b.sem_num = 0;
     37     sem_b.sem_op = -1;
     38     sem_b.sem_flg = SEM_UNDO;
     39     if(semop(semid, &sem_b, 1) == -1)
     40     {
     41         fprintf(stderr, "P() failed
    ");
     42         return -1;
     43     }
     44     return 0;
     45 }
     46 
     47 int V()
     48 {
     49     struct sembuf sem_b;
     50     sem_b.sem_num = 0;
     51     sem_b.sem_op = 1;
     52     sem_b.sem_flg = SEM_UNDO;
     53     if(semop(semid, &sem_b, 1) == -1)
     54     {
     55         fprintf(stderr, "V() failed
    ");
     56         return -1;
     57     }
     58     returi 0;
     59 }
     60 
     61 int main(int argc, char *argv[])
     62 {
     63     char msg = 'X';
     64     int i=0;
     65 
     66     if(argc > 1 && !strcmp(argv[1], "0"))
     67     {
     68         /* first user sem */
     69         if(set_semvalue() == -1)
     70         {
     71             fprintf(stderr, "Failed to initialize semaphore
    ");
     72             return -1;
     73         }
     74         msg = argv[1][0];
     75         sleep(2);
     76     }
     77 
     78     semid = semget((key_t)1234, 1, 0666|IPC_CREAT);
     79     if(semid == -1)
     80     {
     81         printf("semget error
    ");
     82         return -1;
     83     }
     84     for(i=0;i<10;i++)
     85     {
     86         if(P() == -1)
     87             return -1;
     88         printf("%c", msg);
     89         fflush(stdout);
     90         sleep(rand()%3);
     91         printf("%c", msg);
     92         fflush(stdout);
     93         if(V() == -1)
     94             return -1;
     95         sleep(rand()%2);
     96     }
     97     sleep(5);
     98     printf("
    %d - finished
    ", getpid());
     99 
    100     if(argc > 1)
    101         del_semvalue();
    102 
    103     return 0;
    104 }

     第二个竞争了例子:

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <sys/types.h>
     4 #include <unistd.h>
     5 
     6 int main(int argc, char *argv[])
     7 {
     8     char msg = 'X';
     9     int i =0; 
    10     if(argc >1) 
    11         msg = argv[1][0];
    12 
    13     for(i=0;i<10;i++)
    14     {   
    15         printf("%c", msg);
    16         fflush(stdout);
    17         sleep(rand()%3);
    18         printf("%c", msg);
    19         fflush(stdout);
    20         sleep(rand()%2);
    21     }   
    22     sleep(10);
    23     printf("
    %d - finished
    ", getpid());
    24     return 0;
    25 }

     运行方法:

    ./a.out 0 &./a.out 
    无欲速,无见小利。欲速,则不达;见小利,则大事不成。
  • 相关阅读:
    MySQL数据库优化详解(收藏)
    怎么设置Linux swap分区?方法教程
    js获取IP地址多种方法实例教程
    JQuery设置获取下拉菜单选项的值 多实例
    JQuery中serialize()、serializeArray()和param()用法举例
    javascript 获取函数形参个数
    mysql SQLyog导入csv数据失败怎么办?
    今天离职了!
    Asp.Net Core 使用Quartz基于界面画接口管理做定时任务
    Asp.Net Core中使用Swagger,你不得不踩的坑
  • 原文地址:https://www.cnblogs.com/ch122633/p/8065781.html
Copyright © 2020-2023  润新知