Fork () переключение между родительским и дочерним процессами - PullRequest
0 голосов
/ 16 декабря 2018

У меня есть программа, которая создает 2 дочерних процесса.Процесс клиента отправляет свой PID процессу сервера, процесс сервера отправляет случайный идентификатор обратно процессу клиента, и, наконец, процесс клиента получает идентификатор и печатает его.

Проблема в моем коде заключается в том, чтоЯ не могу получить порядок исполнения правильно.Я могу установить связь клиент-клиент-сервер или сервер-клиент-клиент. Как я могу заставить программу работать в правильном порядке?

Я пытаюсь смоделировать эту связь клиент-сервер, чтобы затем масштабировать ее для нескольких клиентов, взаимодействующих с одним сервером, чтобыисходный процесс не должен учитывать решение.

Спасибо за вашу помощь.

Текущий вывод:

Клиент (2971): Получен новый идентификатор 32767 с сервера.

Сервер (2972): получил pid 2971 от клиента.Отправка нового идентификатора.

Ожидаемый результат:

Сервер (2972): Получен pid 2971 от клиента.Отправка нового идентификатора.

Клиент (2971): Получен новый идентификатор 32767 с сервера.

int main (int argc, char *argv[])
{
   int petitionPipe[2];
   int responsePipe[2];

if (pipe(petitionPipe) != 0 || pipe(responsePipe) != 0)
{
    err_exit("Failed to open a pipe\n");
}

int client = fork();
int server = 0;

if (client > 0)
{
    server = fork();
}

if (client < 0 || server < 0)
{
    err_exit("fork() failed\n");
}

else if (client == 0)
{
    clientPetition(petitionPipe, responsePipe);
}

else if (server == 0)
{
    serverResponse(petitionPipe, responsePipe);
}

if (client == 0)
{
    clientResult(petitionPipe, responsePipe);
}

return 0;


static void clientPetition(int *petitionPipe, int *responsePipe)
 {
    pid_t pid;

    close(petitionPipe[READ]);
    close(responsePipe[WRITE]);
    close(responsePipe[READ]);

    pid = getpid();

    write(petitionPipe[WRITE], &pid, sizeof(pid_t));
 }

static void serverResponse(int *petitionPipe, int *responsePipe)
 {
    pid_t pid;
    int newID;

    close(petitionPipe[WRITE]);
    close(responsePipe[READ]);

    read(petitionPipe[READ], &pid, sizeof(pid));

    printf("Server(%d): Recived pid %d from client. Sending new ID.\n\n", getpid(), pid);

    srand(pid);
    newID = rand() % 100;

    write(responsePipe[WRITE], &newID, sizeof(newID));
 }

static void clientResult(int *petitionPipe, int *responsePipe)
{
    int newID;

    close(petitionPipe[READ]);
    close(petitionPipe[WRITE]);
    close(responsePipe[WRITE]);

    read(responsePipe[READ], &newID, sizeof(newID));

    printf("Client(%d): Recieved new ID %d from Server.\n\n", getpid(), newID);
}

1 Ответ

0 голосов
/ 16 декабря 2018

Хотя я не запускал ваш код, в вашем коде есть 3 процесса.

  Main process
  |         |
  |         |
  v         v
Server    Child

Практическое правило: Не забудьте выполнить процедуры захоронения, даже если вы уверены, что дочерний процесс завершает предшествующий родительский процесс.Вызывая wait(...), вы сообщаете операционной системе, что я сделал все для моего ребенка, чтобы теперь вы могли очистить выделенные поля и т. Д.

Итак, вам нужно подождать обоих детей, прежде чем позволитьвозврат основного процесса.Что делать, если нет возможности начать выполнение серверного или клиентского процесса?Живой мертвец??Сирота ??

AFAIS, если мы проигнорируем вышеупомянутый случай, я думаю, что ваша программа работает, как ожидалось.Печать без заказа не означает, что он работает неправильно.Вы не можете решить от имени ОС, какой процесс запускается первым и т. Д., За исключением того, что вы можете определить их через критическую секцию или концепции прерываний, такие как семафор или сигнализация, соответственно.

...