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

示例:

 oflag = IPC-CREAT | IPC-EXCL | SVSEM-MODE;
if ( (semid = semget (key, , oflag) ) >= ) {
/* success, we are the first, so initialize */
arg.val = ;
semctl (semid, , SETVAL, arg) ; } else if (errno == EEXIST) {
/* already exists, just open */
semid = semget(key, , 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已经初始化完成。

示例:

 oflag = IPC-CREAT | IPC-EXCL | SVSEM-MODE;
if ( (semid = semget (key, , oflag) ) >= ) {
/* success, we are the first, so initialize */
arg.val = ;
semctl (semid, , SETVAL, arg) ; else if (errno == EEXIST) {
/* someone else has created; make sure it's initialized */
semid = semget(Ftok(L0CK-PATH, ). , SVSEM-MODE);
arg.buf = &seminfo;
for (i = ; i < MAX-TRIES; i++) (
semctl(semid, , IPC-STAT, arg);
if(arg.buff->sem_otime!=) //判断初始化已经被另一个进程完成。
goto init;
sleep () ;
}
err-quit("semget OK, but semaphore not initialized");
} else
err-sys("semget error"); semop(semid, ... ) ; /* decrement the semaphore by 1 */

Linux System V Semaphore semget多进程同时创建缺陷解决方法的更多相关文章

  1. linux下安装Oracle时交换空间不足的解决方法

    摘:linux下安装Oracle时交换空间不足的解决方法 linux上安装Oracle时交换空间不足的解决办法 增加交换空间有两种方法: 严格的说,在系统安装完后只有一种方法可以增加swap,那就是本 ...

  2. linux使用su切换用户提示 Authentication failure的解决方法& 复制文件时,报cp: omitting directory `XXX'

    linux使用su切换用户提示 Authentication failure的解决方法:这个问题产生的原因是由于ubtun系统默认是没有激活root用户的,需要我们手工进行操作,在命令行界面下,或者在 ...

  3. 无法读取配置节 system.serviceModel 因为它缺少节声明的解决方法

    无法读取配置节 system.serviceModel 因为它缺少节声明的解决方法,需要的朋友可以参考下 在Windows Server2008 R2中的IIS7中部署WCF服务时报出如题错误: HT ...

  4. Linux system V

    Sysvinit 的小结 Sysvinit 的优点是概念简单.Service 开发人员只需要编写启动和停止脚本,概念非常清楚:将 service 添加/删除到某个 runlevel 时,只需要执行一些 ...

  5. Linux system v 共享内存

    system v 共享内存 #include <sys/types.h> #include <sys/shm.h> int shmget(key_t key, size_t s ...

  6. 外星人电脑出现the system is running in low graphics mode的解决方法

    问题现象: 执行删除GCC5.4.0: sudo  apt-get remove gcc gcc-5重启电脑后,就显示the system is running in low graphics mod ...

  7. "System.Security.Cryptography.CryptographicException: 拒绝访问" 问题的解决方法

    .net web程序使用rsa算法进行加解密时,程序报告“System.Security.Cryptography.CryptographicException: 拒绝访问”错.按网上搜的解决方法做了 ...

  8. System.Data.OleDb.OleDbException: 未指定的错误的解决方法

    异常详细信息: System.Data.OleDb.OleDbException: 未指定的错误 这个错误是access数据库特有的错误,当access频繁读取或操作过多的时候就会发生这个错误,微软官 ...

  9. MySQL函数不能创建的解决方法

    MySQL函数不能创建,是一个很麻烦的问题,下面就为您提供了一个解决此问题的方法,如果您也遇到过类似的问题,不妨一看. http://database.51cto.com/art/201010/229 ...

随机推荐

  1. 新转移注意(caffe):ImportError: libcudart.so.7.0: cannot open shared object file: No such file or directory

    https://github.com/NVIDIA/DIGITS/issues/8 For this error ImportError: libcudart.so.7.0: cannot open ...

  2. BZOJ4977: [[Lydsy1708月赛]跳伞求生(不错的贪心)

    4977: [[Lydsy1708月赛]跳伞求生 Time Limit: 5 Sec  Memory Limit: 256 MBSubmit: 446  Solved: 142[Submit][Sta ...

  3. C-语言第二次作业(大一下)

    要求一.设计过程                                                       作业(1) 1.提交列表 6-7 删除字符串中数字字符 2.设计思路(6分 ...

  4. vue-cli项目配置mock数据(新版本)

    最新的vue-webpack-template 中已经去掉了dev-server.js 但是要进行模拟后台数据的,如何模拟本地数据操作? 解决方法: dev-server.js 改用webpack-d ...

  5. SSH学习之四 OpenSSH安全

             OpenSSH是Linux/Unix下一款加密通讯软件.同一时候也是我们用来远程控制Linux/Unixserver重要的必装软件. 对于各版本号的Linux及Unix发行版而言,O ...

  6. GridView 绑定数据的常用指定格式。

    形式 语法 结果 注释 数字 {0:N2} 12.36   数字 {0:N0} 13   货币 {0:c2} $12.36   货币 {0:c4} $12.3656   货币 "¥{0:N2 ...

  7. 设置cassandra用户名和密码

    参考http://zhaoyanblog.com/archives/307.html 修改cassandra.yaml配置文件 把默认的 authenticator: AllowAllAuthenti ...

  8. Bootstrap-Other:HTML编码规范

    ylbtech-Bootstrap-Other:HTML编码规范 1.返回顶部 1. Bootstrap HTML编码规范 语法 用两个空格来代替制表符(tab) -- 这是唯一能保证在所有环境下获得 ...

  9. 使用libssh2连接到远程服务器

    libssh2-1.7.0.tar.gz  示例代码:libssh2-1.7.0.tar.gz\libssh2-1.7.0\example 官网示例 https://www.libssh2.org/e ...

  10. php删除制定文件及文件夹

    php遍历一个文件夹内的所有文件和文件夹,并删除所有文件夹和子文件夹下的所有文件的代码,通过递归方式实现达到清空一个目录的效果,代码简单实用. 用到的函数: scandir($path) 遍历一个文件 ...