From: Hiro on 20 Dec 2009 04:28 Hello, I'm trying to test program that generates 3 children, 1st, 2nd, and 3rd, and force to execute them in reverse order(3rd->2nd->1st), using 2 semaphoes. However, when I operate against 2 semaphoe at onece using following, if( semop(sem_bin, sem_buf_v1_p2, 2) == -1){ the program seems to be deadlock. On the other hand, when I use following instead above, it works as expected. if( semop(sem_bin, &sem_buf_both_v[0], 1) == -1){ perror("error to get semaphoe"); exit(-1); } if( semop(sem_bin, &sem_buf_both_p[1], 1) == -1){ perror("error to get semaphoe"); exit(-1); } But I was thinking both of them are equivalent. Could someone tell me what's going wrong? The entire code is following, and I'm working on Ubuntu, and gcc. Linux HOGE2 2.6.24-23-generic #1 SMP Wed Apr 1 21:47:28 UTC 2009 i686 GNU/Linux #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/wait.h> #include <sys/ipc.h> #include <sys/sem.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> int main(void) { int i, sem_bin; int pid, ret; int semval; struct sembuf sem_buf_both_v[2] = { { 0, // first semaphoe to operate 1, // operation (V) SEM_UNDO, // if process terminates, automatically undone }, { 1, // second semaphoe to operate 1, // operation (V) SEM_UNDO, // if process terminates, automatically undone } }; struct sembuf sem_buf_both_p[2] = { { 0, // first semaphoe to operate -1, // operation (P) SEM_UNDO, // if process terminates, automatically undone }, { 1, // second semaphoe to operate -1, // operation (P) SEM_UNDO, // if process terminates, automatically undone } }; /* V to first, then P to second */ struct sembuf sem_buf_v1_p2[2] = { { 0, // second semaphoe to operate 1, // operation (V) SEM_UNDO, // if process terminates, automatically undone }, { 1, // first semaphoe to operate -1, // operation (P) SEM_UNDO, // if process terminates, automatically undone }, }; key_t key = time(0); /* * get semaphe * here, allocating 2 semaphoe with one key * */ if( (sem_bin = semget(key, 2, 0666|IPC_CREAT)) < 0 ){ perror("error to get semaphoe"); exit(-1); } /* make first child */ pid = fork(); if(pid == 0){ /* * p operation to first semaphoe **/ if( semop(sem_bin, &sem_buf_both_p[0], 1) == -1){ perror("error to get semaphoe"); exit(-1); } /* * v operation to first semaphoe * ( wake up second child ) * if( semop(sem_bin, &sem_buf_both_v[0], 1) == -1){ perror("error to get semaphoe"); exit(-1); } if( semop(sem_bin, &sem_buf_both_p[1], 1) == -1){ perror("error to get semaphoe"); exit(-1); } **/ if( semop(sem_bin, sem_buf_v1_p2, 2) == -1){ perror("error to get semaphoe"); exit(-1); } pid = getpid(); printf("first child :[%d]\n", pid); exit(0); }else if (pid == -1){ perror("fork error"); exit(-1); } /* make second child */ pid = fork(); if(pid == 0){ /* child */ if( semop(sem_bin, &sem_buf_both_p[0], 1) == -1){ perror("error to get semaphoe"); exit(-1); } pid = getpid(); fprintf(stderr, "second child:[%d]\n", pid); if( semop(sem_bin, sem_buf_both_v, 2) == -1){ perror("error to get semaphoe"); exit(-1); } exit(0); }else if (pid == -1){ perror("fork error"); exit(-1); } /* make third child */ pid = fork(); if(pid == 0){ /* child */ pid = getpid(); printf("third child:[%d]\n", pid); /* release first semaphoe */ if( semop(sem_bin, sem_buf_both_v, 1) == -1){ perror("error to get semaphoe"); exit(-1); } exit(0); }else if (pid == -1){ perror("fork error"); exit(-1); } while(wait(&ret)>=0){ printf("wait!!"); } /* remove semaphoe */ if( semctl(sem_bin, 0, IPC_RMID) < 0 ){ perror("error to remove semaphoe"); exit(-1); } return 0; } Thank you -- Yoshi
|
Pages: 1 Prev: Virtual IP setup Problem Next: Two programs with same logic |