我必須使用進程創建競爭條件程序,我也是如此。現在,我正在嘗試使用信號量來解決它。我有兩個關鍵部分,我試圖使用我在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);
}
如果您沒有發佈與sephamores交互的代碼,我無法幫助您獲取信號量。 – netcoder 2013-02-20 18:11:03
對不起,我用缺失函數的代碼更新了我的問題。 – thibaultcha 2013-02-20 18:47:28
爲什麼不使用經典'sem_init','sem_post'和'sem_wait'? – 2013-02-20 19:03:49