- 论坛徽章:
- 0
|
问题:关于freebsd中system V信号灯实现的问题
环境:Freebsd4.10, gcc3.3
来源:unp2 p254页 建立信号量的问题
在这页中,有一个例程 (图11.7)其中初始化信号灯的部分,我摘录如下。
- #define SVSEM_MODE (SEM_R | SEM_A | SEM_R>;>;3 | SEM_R>;>;6)
- #define CRSEM_MODE IPC_CREAT | IPC_EXCL | SVSEM_MODE
- static int createSemaphore()
- {
- union semun arg;
- struct semid_ds seminfo;
- key_t logkey = ftok(FILE_PASSWORD_LOCK, 0); // 建立ipc标识
- if ( logkey == -1 )
- {
- log_msg("error on ftok");
- return -1; // 没有找到文件或没有权限读取它
- }
-
- semid = semget(logkey, 1, CRSEM_MODE); // 新建信号量
- if ( semid >;= 0 )
- {
- /* 4success, we're the first so initialize */
- arg.val = 1;
- if ( -1 == semctl(semid, 0, SETVAL, arg) )
- {
- log_msg("error on setctl");
- return -1;
- }
- }
- else if (errno == EEXIST)
- {
- /* 4someone else has created; make sure it's initialized */
- semid = semget(logkey, 1, SVSEM_MODE);
- if ( -1 == semid )
- {
- return -1;
- }
-
- arg.buf = &
- int i;
- for (i = 0; i < MAX_TRIES; i++) {
- if ( -1 == semctl(semid, 0, IPC_STAT, arg) )
- {
- log_msg("set value in max tries error");
- return -1;
- }
-
- if (arg.buf->;sem_otime != 0) // 就是这里,freebsd4上不起作用
- goto init;
- sleep(1);
- }
- log_msg("timeout error");
- return -1; //semget OK, but semaphore not initialized
- }
- else
- {
- return -1; // semget error
- }
- init:
- initflag = 1;
- postop.sem_num = 0; /* and init the two semop() structures */
- postop.sem_op = 1;
- postop.sem_flg = SEM_UNDO;
- waitop.sem_num = 0;
- waitop.sem_op = -1;
- waitop.sem_flg = SEM_UNDO;
-
- return 0;
- }
复制代码
问题在于,当信号灯已经建立后,这段程序会检查信号灯是否已经被初始化。在程序中,如果 sem_otime == 0 ,则等待创建信号灯的进程完成它的初始化工作,如果sem_otime != 0,则信号灯已经被初始化完成。
在我的程序中,发现除了创建信号灯的进程外,其它进程都拿不到这个锁。debug后发现,sem_otime总是==0,所以在这里死锁。
我觉得在freebsd4中,sem_otime总是为0。系统在初始化信号灯时,没有正确的初始化这个变量,没有按照system V的标准来实现。大家看看我的理解是否有误?
除了freebsd, 别的系统我还没有测试过,不知道结果是否有普遍性 |
|