Неожиданная синхронизация поведения с использованием вызовов kill и pause - PullRequest
0 голосов
/ 25 января 2019

У меня есть простая программа, которая принимает пользовательский ввод N, поочередно начинает делать N-1 потомков, т.е. ith процесс является дочерним по отношению к (i-1)th процессу. Первоначально существует только один процесс, который создает один дочерний процесс, который, в свою очередь, создает другой дочерний процесс и т. Д.
После того, как у меня есть N процессов, я должен выполнить серию команд SYN и ACK, таким образом, чтобы потомок передает ACK родителю, пока мы не достигнем первого процесса, который затем передает SYN дочерним процессам, пока мы не достигнем последнего процесса. Этот цикл продолжается указанное количество итераций max_itr. Пример в конце.
Это программа, которую я придумал:

#include <stdio.h>
#include <signal.h>

int N, max_itr, itr, present_i, cid, pid;

void handler1()
{
    ++itr;
    if(itr > max_itr)
    {
        kill(cid, SIGUSR1);
        return;
    }
    printf("Syn:%d\t",getpid());
    if(present_i < N)
    {
        kill(cid, SIGUSR1);
    }
    else
    {
        printf("\n");
        printf("Ack:%d\n",getpid());
        kill(getppid(), SIGUSR2);
    }
}

void handler2()
{
    if(present_i > 1)
    {
        printf("Ack:%d\n",getpid());
        kill(getppid(), SIGUSR2);
    }
    else{
        ++itr;
        if(itr > max_itr)
        {
            kill(cid, SIGUSR1);
            return;
        }
        printf("Syn:%d\t",getpid());
        if(present_i < N)
        {
            kill(cid, SIGUSR1);
        }
        else
        {
            printf("\n");
            kill(getppid(), SIGUSR2);
        }
    }
}

int main()
{
    scanf("%d",&N);
    signal(SIGUSR1, handler1);
    signal(SIGUSR2, handler2);
    itr = 0;
    max_itr = 5; // fixed
    present_i = 1;
    // printf("%d\t%d\n",getpid(),present_i);
    while(present_i<N)
    {
        cid = fork();
        if(cid == 0)
        {
            present_i ++;
            // printf("%d\t%d\n",getpid(),present_i);
        }
        else
        {
            break;
        }
    }
    if(present_i == N)
    {
        printf("Ack:%d\n",getpid());
        kill(getppid(), SIGUSR2);
        pause();
    }
    while(itr<=max_itr) pause();
    return 0;
}

Я использую SIGUSR1 сигналы для распространения SYN команд на дочерние процессы и SIGUSR2 сигналов для распространения ACK на родительские процессы. Но я не получаю ожидаемый результат, и программа приостанавливается после первой итерации. Я ожидаю такой вывод:

INPUT: N=3, max_itr=2
Processes created: 2341, 2342 (child of 2341), 2343 (child of 2342)
OUTPUT:
Ack:2343
Ack:2342
Ack:2341
Syn:2341    Syn:2342    Syn:2343
Ack:2343
Ack:2342
Ack:2341
Syn:2341    Syn:2342    Syn:2343

Мне не удалось выяснить причину зависания этой программы.

...