2013-02-20 47 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