【问题标题】:Forked Children Initialization Sempahore Blocking分叉的孩子初始化信号量阻塞
【发布时间】:2017-12-04 19:57:56
【问题描述】:

我的目标是通过一个共同的 int 值来同步分叉的进程。

我需要 fork 一些子节点,但还要信号量阻止它们,直到所有子节点都被 fork。

此变量 (init_num) 必须首先等于我拥有的进程数,然后这些进程才能继续执行其功能。

我的代码:


    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 我的程序死锁并停在那里。

输出:

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()

【问题讨论】:

  • 请将您的代码报价升级为minimal reproducible example
  • @Yunnosch 我会编辑,这样更容易理解,但它很长,我认为我的问题出在给定的部分。
  • 照顾最小的!=FullCopyOfEverything
  • @Yunnosch 确实,我修好了
  • *init_num++ 并没有按照你的想法去做。

标签: c fork deadlock semaphore


【解决方案1】:

启用警告,你会看到

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

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

        (*init_num)++;

【讨论】:

  • 先生,您是救生员。你完全正确。我之前启用了 -Wall 但没有理解这个含义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-16
相关资源
最近更新 更多