- 论坛徽章:
- 0
|
在研究学习信号量的时候,发现了一个奇怪了问题,如果在信号量的处理过程中调用usleep睡眠等待,那么会出现,进程A上锁后,进程B也可以上锁(在进程A没有解锁的条件下),但是如果去掉了usleep,是可以正常运行的。代码如下求大神指导,谢谢!!!
#include <basefun.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#define SEM_KEY 8999
#define SVSEM_MODE 0644
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *__buf;
};
int sem_init();
int sem_lock(int semid);
int sem_unlock(int semid);
int sem_delete(int semid);
int sem_deal(int semid);
int sem_count(int semid);
void test_wait(int loop);
int main()
{
int rs, semid;
semid = sem_init();
_CHECK_RS(semid, -1, -1);
if (0 == fork()) {
rs = sem_deal(semid);
_CHECK_RS(rs, -1, -1);
return 0;
}
rs = sem_deal(semid);
_CHECK_RS(rs, -1, -1);
GET_INPUT;
sem_delete(semid);
return 0;
}
int sem_init() {
int rs, semid;
int flag = IPC_CREAT | IPC_EXCL | SVSEM_MODE;
sembuf sb;
semid = semget(SEM_KEY, 1, flag);
_CHECK_RS(semid, -1, -1);
memset(&sb, 0, sizeof(sb));
sb.sem_num = 0;
sb.sem_op = 1;
sb.sem_flg = SEM_UNDO;
rs = semop(semid, &sb, 1);
_CHECK_RS(rs, -1, 1);
return semid;
}
int sem_delete(int semid) {
int rs;
rs = semctl(semid, 0, IPC_RMID, NULL);
_CHECK_RS(rs, -1, -1);
return 0;
}
int sem_lock(int semid) {
int rs;
sembuf sb;
memset(&sb, 0, sizeof(sb));
sb.sem_num = 0;
sb.sem_op = -1;
sb.sem_flg = SEM_UNDO;
rs = semop(semid, &sb, 1);
_CHECK_RS(rs, -1, -1);
return 0;
}
int sem_unlock(int semid) {
int rs;
sembuf sb;
memset(&sb, 0, sizeof(sb));
sb.sem_num = 0;
sb.sem_op = 1;
sb.sem_flg = SEM_UNDO;
rs = semop(semid, &sb, 1);
_CHECK_RS(rs, -1, -1);
return 0;
}
int sem_deal(int semid) {
int i, rs;
struct timespec stime = {0, 100};
for (i = 0; i < 5; i++) {
rs = sem_lock(semid);
_CHECK_RS(rs, -1, -1);
P("[%ld] lock succeed, count[%d] ...\n", getpid(), sem_count(semid));
rs = sem_unlock(semid);
_CHECK_RS(rs, -1, -1);
P("[%ld] unlock succeed, count[%d] ...\n", getpid(), sem_count(semid));
usleep(100);
}
return 0;
}
int sem_count(int semid) {
union semun arg;
struct semid_ds seminfo;
arg.buf = &seminfo;
return semctl(semid, 0, GETVAL, arg);
}
void test_wait(int loop) {
for (int i = 0; i < loop; i++)
;
} |
|