2013-02-20 42 views
0

我必须使用进程创建竞争条件程序,我也是如此。现在,我正在尝试使用信号量来解决它。我有两个关键部分,我试图使用我在initStem()中使用semctl()创建的信号来保护它们。 P()V()递增和递减第二个参数中指定的信号量的互斥量。使用信号量以避免竞争条件

遗憾的是,似乎我的比赛状态仍然存在:我的输出是:

value in parent: 4 
value after child exec: 4 

当它应该是:

value in parent: 4 
value after child exec: 5 

(5 + 1 - 1 = 5 ... )

这里是我的代码:

#define KEY 4567 
#define PERMS 0660 
#define ID_PROJ "race" 
#define NB_SEMAPHORES 1 

int initSem(char **argv); 
int P(int semid, int semnum); 
int V(int semid, int semnum); 

int main(int argc, char **argv) { 

    int id, pid1; 
    int *shared; 
    int tmp; 

if ((id = shmget(KEY, 2*sizeof(int), IPC_CREAT | PERMS)) == -1) { 
    perror("shmget"); 
    exit(-1); 
} 

shared=(int *)shmat(id, NULL, 0); 
shared[0]=5; // value 
shared[1]=initSem(argv); // semaphore id 

if ((pid1=fork()) == 0) { 
    P(shared[1], 0); // Start critical section 
    tmp=shared[0]; 
    tmp++; 
    sleep(2); 
    shared[0]=tmp; 
    V(shared[1], 0); // End critical section 
    exit(0); 
} 
else { 
    P(shared[1], 0); // Start 
    tmp=shared[0]; 
    tmp--; 
    sleep(4); 
    shared[0]=tmp; 
    V(shared[1], 0); // End 

    printf("value in parent: %d\n", shared[0]); 

    waitpid(pid1, NULL, 0); 
    printf("value after child exec: %d\n", shared[0]); 
    shmctl(id, IPC_RMID, NULL); 
} 
} 

所以我想知道:我正确使用我的信号量?我是否通过在我的两个进程中使用相同的信号量来做正确的事情?

编辑:

这里有3个功能,我使用与我的信号灯互动:

int initSem(char **argv) { 
    int i,semid; 
    key_t key=ftok(argv[0], 'P'); 
    semid=semget(key, NB_SEMAPHORES, IPC_CREAT | PERMS); 
    for(i=0 ; i<NB_SEMAPHORES ; i++) 
      semctl(key, i, SETVAL, 1); 
    return semid; 
} 

int P(int semid, int semnum) { 
    struct sembuf op; 
    op.sem_num=semnum; 
    op.sem_op=-1; 
    op.sem_flg=0; 
    semop(semid, &op, 1); 
} 

int V(int semid, int semnum) { 
    struct sembuf op; 
    op.sem_num=semnum; 
    op.sem_op=1; 
    op.sem_flg=0; 
    semop(semid, &op, 1); 
} 
+0

如果您没有发布与sephamores交互的代码,我无法帮助您获取信号量。 – netcoder 2013-02-20 18:11:03

+0

对不起,我用缺失函数的代码更新了我的问题。 – thibaultcha 2013-02-20 18:47:28

+0

为什么不使用经典'sem_init','sem_post'和'sem_wait'? – 2013-02-20 19:03:49

回答

0

好了,所以问题出在我使用的initSem

semctl(key, i, SETVAL, 1); 

代替

semctl(semid, i, SETVAL, 1); 

否则我的代码是正确的。

0

确保用pshared集创建使用sem_init()信号量非零

+0

事情是我正在尝试使用semget和semctl来实现这一点。我用缺失函数的代码更新了我的问题。 – thibaultcha 2013-02-20 18:48:35