c - fork 子级初始化信号量阻塞

标签 c fork deadlock semaphore

我的目标是通过公共(public) int 值同步 fork 进程。

我需要 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()

最佳答案

启用警告,您将看到

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

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

        (*init_num)++;

关于c - fork 子级初始化信号量阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47641049/

相关文章:

c - C 中指向数组元素的指针

c - 如何编译 FreeBSD 的修改版本?

c - 使用套接字的事件服务(端口)

c - 单线程进程中的 pthread 互斥体是否需要在 fork() 上重新初始化?

c - 在链中 fork N 个进程

asp.net - 同时启动的两个并行请求依次执行

c# - 如何获得多个数组的所有组合?

Python fork : 'Cannot allocate memory' if process consumes more than 50% avail. 内存

C - 这个简单的 transaction() 函数如何才能完全避免死锁?

java - 线程被锁定在 java.util.Stack