信号量死锁/阻止所有进程

时间:2017-12-04 19:57:56

标签: c fork deadlock semaphore

sem_wait和sem_post意外结果

我的目标是通过公共int值同步分叉进程。 那个int号(init_num)必须首先等于我拥有的进程,然后进程可以继续它们的功能。

我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>      /*pid_t sem_t key_t   */
#include <sys/ipc.h>        /* IPC_RMID IPC_CREAT */
#include <sys/shm.h>        /* shared memory      */ 
#include <fcntl.h>          /* O_CREAT, O_EXEC  (for shm_open)  */
#include <semaphore.h>      /* POSIX semaphores (sem open etc.) */
#include <errno.h>          /* errno, ECHILD            */  
#include <sys/wait.h>       /****************************/

pid_t pid;
key_t key;
sem_t *sem;
sem_t *sem2;
int shmid;

int main(int argc , char* argv[])
{
    if (argc < 2){
        printf("Incorrect number of arguments given!\n");
        exit(-1);
    }

    int num_strings = argc - 2; 
    int reps = atoi (argv[1]);


    //  SHARED MEMORY  // 


    key = 9876;

    shmid = shmget( key , sizeof(int) , 0644 | IPC_CREAT);
    if ( shmid < 0 ){
        perror("shmget\n");
        exit(-1);
    }

    // SHARED MEMORY INITIATED //

    int *init_num;
    init_num = shmat ( shmid , NULL , 0);
    *init_num = 0;

    // SEMAPHORES TIME //

    sem = sem_open("TheSem", O_CREAT | O_EXCL , 0644 , 1);

    sem2 = sem_open("TheSem2", O_CREAT | O_EXCL , 0644 , 0);

    // SEMAPHORE DONE //

    int i;
    // FORKS //
    for (i=0; i<num_strings; i++){
        pid = fork();

        if (pid < 0) {
                    printf ("Fork error.\n");

            sem_unlink("TheSem");
            sem_close(sem);

            sem_unlink("TheSem2");
            sem_close(sem2);
            }
            else if ( pid == 0)
                    break;
        }

    // FATHER //
    if ( pid !=0 && pid!=-1 ){
        int status;
                while(pid = waitpid (-1,NULL,0)){
                        if(errno == ECHILD)
                                break;
                }         
        shmdt (init_num);
        shmctl (shmid, IPC_RMID, 0);

        sem_unlink("TheSem");
        sem_close(sem);

        sem_unlink("TheSem2");
        sem_close(sem);
        }

    int n;
    //CHILDREN //
    if( pid == 0){
        sem_wait(sem);
            init();
            *init_num++;
        sem_post(sem);

        if (*init_num < num_strings ){
            sem_wait(sem2);
        }else{
            for(n=0 ; n <=num_strings-1; n++){
                sem_post(sem2);
            }
        }

        // DISPLAY // 
        for(n=0; n < reps; n++){
            sem_wait(sem);
                display(argv[2+i]);
            sem_post(sem);
        }

    }
return(0);
}

*init_num位于共享内存空间中。

问题是在所有进程完成后init()*init_num应该等于processes我的程序死锁并在那里停止!! 没有display()部分。

我正在使用POSIX信号量和一般实现。 所有必要的库都包含并编译得很好。 此外,所有信号量和共享内存空间都已清理。

输出:

STARTING: pid 1268, tid 1157203712
STARTING: pid 1270, tid 1157203712
STARTING: pid 1269, tid 1157203712
STARTING: pid 1271, tid 1157203712
STARTING: pid 1272, tid 1157203712
STARTING: pid 1273, tid 1157203712
STARTING: pid 1274, tid 1157203712
STARTING: pid 1275, tid 1157203712  // these are init()

通缉输出:

STARTING: pid 1268, tid 1157203712
STARTING: pid 1270, tid 1157203712
STARTING: pid 1269, tid 1157203712
STARTING: pid 1271, tid 1157203712
STARTING: pid 1272, tid 1157203712
STARTING: pid 1273, tid 1157203712
STARTING: pid 1274, tid 1157203712
STARTING: pid 1275, tid 1157203712
// then the display();

1 个答案:

答案 0 :(得分:0)

启用警告,您将看到

warning: expression result unused [-Wunused-value]
        *init_num++;
        ^~~~~~~~~~~

立即显示您的问题。孩子们不会增加值:他们递增指针。从技术上讲,它是UB,但实际上它们都读为0.将其改为

        (*init_num)++;