zoukankan      html  css  js  c++  java
  • Linux System V Semaphore semget多进程同时创建缺陷解决方法

    System V Semaphore的创建过程缺陷是创建与赋初值由两个函数完成,这会导致两个进程同时创建的话会出现竞争和不一致状态,即使是使用了IPC-EXCL标记。

    示例:

     1 oflag = IPC-CREAT | IPC-EXCL | SVSEM-MODE;
     2 if ( (semid = semget (key, 1, oflag) ) >= 0) {
         /* success, we are the first, so initialize */
     3     arg.val = 1;
     4     semctl (semid, 0, SETVAL, arg) ;
     
     5 } else if (errno == EEXIST) {
         /* already exists, just open */
     6     semid = semget(key, 1, SVSEM-MODE);
     
     7 } else
     8     err-sys("semget error");
     
     9 semop(semid, ... ) ; /* decrement the semaphore by 1 */

    第一个创建进程可能执行语句1,2,3进行创建,而第二个进程创建失败,执行1,2,5,6,9。即第二个进程在第一个进程虽然创建成功但是还没来得及赋初值(第4行)时,已经被第二个进程拿去用了,而其获取的初值是未定义的,所以第14行的操作也就是未定义的。

    一种改进方法是,循环查询semid_ds中的成员sem_otime,它在sem创建成功后是0,然后记录sem被执行的上一次操作的时间。通过判断sem_otime不为0即可知道sem已经初始化完成。

    示例:

    1 oflag = IPC-CREAT | IPC-EXCL | SVSEM-MODE;
    2 if ( (semid = semget (key, 1, oflag) ) >= 0) {
           /* success, we are the first, so initialize */
    3     arg.val = 1;
    4     semctl (semid, 0, SETVAL, arg) ;
      
    5 else if (errno == EEXIST) {
         /* someone else has created; make sure it's initialized */
    6    semid = semget(Ftok(L0CK-PATH, 0). 1, SVSEM-MODE);
    7    arg.buf = &seminfo;
    8    for (i = 0; i < MAX-TRIES; i++) (
    9        semctl(semid, 0, IPC-STAT, arg);
    10       if(arg.buff->sem_otime!=0) //判断初始化已经被另一个进程完成。
    11           goto init;
    12       sleep (1) ;
    13   }
    14    err-quit("semget OK, but semaphore not initialized");
    15 } else
    16      err-sys("semget error");
     
    17 semop(semid, ... ) ; /* decrement the semaphore by 1 */    
  • 相关阅读:
    Cinema in Akiba(线段树)
    SGU
    632-掷骰子
    ZOJ
    nyoj 1129 Salvation(搜索)
    symbol table meaning
    C/C++编译和链接过程详解 (重定向表,导出符号表,未解决符号表)
    编译链接 C++
    while(cin.eof)出错 poj
    华为oj 购物单
  • 原文地址:https://www.cnblogs.com/NerdWill/p/5006739.html
Copyright © 2011-2022 走看看