Я пишу сервер, который fork () отключает дочерний процесс, когда он принимает соединение с сокетом.
Когда ребенок общается с клиентом, он должен отправить часть этой информации обратно родителю. Для этого я использую трубу.
Проблема в том, что когда я пытаюсь сделать IPC родитель-потомок, родительский блок блокирует чтение входных данных от дочернего. Это означает, что, хотя дети работают одновременно, они могут обрабатываться только по одному, потому что все они ожидают родителя.
Мой код выглядит примерно так (проверка ошибок удалена для краткости):
/* loop: wait for clients to connect */
for(;;) {
pipe(write_to_parent); /* create pipe between parent and child */
pipe(write_to_child); /* create pipe between parent and child */
newsockfd = accept(...);
pid = fork();
if (pid == 0) { /* child process */
close(write_to_parent[0]);
close(write_to_child[1]);
printf("Connected!\n");
while ((rc = recv(newsockfd, ...)) > 0) {
/* process socket request */
/* write stuff to parent that is related to what we recv'd from client */
rc = write(write_to_parent[1], &buf, 1024);
}
printf("Disconnected!\n");
exit(0);
} else { /* parent */
close(write_to_parent[1]);
close(write_to_child[0]);
while (read(write_to_parent[0], &buf, 1024) > 0) {
/* accept data from child process, and do some processing */
}
}
}
Итак, мой вопрос, как мне это исправить? Как я могу, чтобы родитель общался с детьми, используя каналы таким образом, чтобы он не блокировал?
Возможно ли это даже с помощью каналов, или я должен использовать совместно используемую память (с семафором, я полагаю) или вместо очереди сообщений? (Я читал этот пост: Сравнение Unix / Linux IPC , но действительно трудно найти примеры того, как эти задачи действительно выполняются.)
Подробнее:
У меня есть тестовая программа, которая выполняет следующие действия:
1. Подключитесь к серверу
2. Сон (5)
3. Отключиться от сервера
Когда я запускаю 2 экземпляра этой программы, сервер выводит это:
connected!
// pause for 5 seconds
disconnected!
connected!
// pause for 5 seconds
disconnected!
Очевидно, обрабатывает каждого клиента по одному.
Когда я удаляю IPC - когда я избавляюсь от конвейера read () и write () от родительского и дочернего, я получаю это:
connected!
connected!
// pause for 5ish seconds
disconnected!
disconnected!
Что я и хочу!
Есть мысли о том, как мне это сделать? (или изменения, которые я должен внести в решение этой проблемы?)
(edit: это часть задания для сетевого класса. Мы внедряем протокол P2P, который использует централизованный сервер для управления одноранговыми узлами. Мы могли бы использовать любой язык, и я решил, что это вызовет бурную реакцию C.)