首页 > 系统服务 > 详细

Linux System V Semaphore semget多进程同时创建缺陷解决方法

时间:2015-11-30 12:56:48      阅读:264      评论:0      收藏:0      [点我收藏+]

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 */    

 

Linux System V Semaphore semget多进程同时创建缺陷解决方法

原文:http://www.cnblogs.com/NerdWill/p/5006739.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!