169 похожих чатов

#Include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <signal.h> enum { max_buf_size = 128

};

// volatile sig_atomic_t ready = 1;

void signal_handler(int sig)
{
// ready = 1;
}

int main()
{
int pipefd[2];
char buf[max_buf_size];
pid_t pid;

signal(SIGUSR1, signal_handler);

if (pipe(pipefd) == -1) {
fprintf(stderr, "Pipe\n");
exit(1);
}

pid = fork();
if (pid == 0) {
char temp[max_buf_size];

close(pipefd[0]);

while (1) {
// if (ready == 1) {
// printf("Enter message from child(Ctrl+D to stop): ");
// if (fgets(temp, max_buf_size, stdin) == NULL)
// break;

// write(pipefd[1], temp, strlen(temp) + 1);
// ready = 0;
// }
printf("Enter message from child(Ctrl+D to stop): ");
if (fgets(temp, max_buf_size, stdin) == NULL)
break;

write(pipefd[1], temp, strlen(temp) + 1);
pause();
}

exit(0);
}

close(pipefd[1]);

while (read(pipefd[0], buf, max_buf_size) > 0) {
if (buf[0] == '\n') {
kill(pid, SIGTERM);
break;
}

printf("Parent read: %s\n", buf);
kill(pid, SIGUSR1);
}

printf("\n");

return 0;
}

Привет, в общем разбираюсь с дочерними процессами и пайпами, изначально сделал без сигналов и вывод дочернего процесса перекрывал родительский. Сейчас такая реализация, но хотел бы узнать, адекватно сделано или есть лучше подходы?
Если что бейте, но не сильно)

7 ответов

12 просмотров

Во-первых, для ликвидации дочернего процесса стоит использовать waitpid. Во-вторых, необходимо обрабатывать исключительные ситуации для read и write. По man pipe вы поймёте, какие коды когда произойдут. В-третьих, нет нужды использовать сигнал для ожидания окончания чтения. В чём тогда смысл двух процессов? Один процесс пишет до тех пор, пока не получит переполнение буфера пайпы, о чем и сообщит и громко упадёт, другой читает, обрабатывает или, если там ошибка, то зависает и происходит переполнение. Короче, сигналы тут конкретно не нужны, как мне кажется. В-четвертых, чтобы завершить работу с пайпом в данной программе, достаточно в родительском процессе читать пока не EOF, а в дочернем просто писать из stdin, пока не EOF(т.е пока не будет нажата комбинация), потом выход из дочернего и в родительском его ликвидация. Наконец, сигнал sigterm для уничтожения использовать не стоит потому, что он просто переводит процесс в другое состояние. У процесса есть 5 состояний: запущен, остановлен, traced, interruptible, uninterrutible. Сигналы переводят его в одно из выше указанных состояний, но не ликвидируют структуру task_struct. Как раз waitpid ждёт изменения состояния и потом очищает ресурс, предотвращая появление т.н процесса zombie.

Diman- Автор вопроса
Oman
Во-первых, для ликвидации дочернего процесса стоит...

Ого, спасибо за столь развернутый ответ. Только я не пойму как без сигналов сделать так чтобы сначала родитель прочитал из канала, а только потом продолжить цикл в дочернем. fgets читает либо до \0 либо до \n, вот после \n хочу записывать и выводить в родителе

Diman
Ого, спасибо за столь развернутый ответ. Только я ...

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

Diman- Автор вопроса
Oman
Это блокирующие операции, поэтому если данных нет,...

Но вот смотри как получается, как запускаю то выводит: ` Enter message from child(Ctrl+D to stop): тут я пишу что хочу\n Enter message from child(Ctrl+D to stop): Parent read: asasf ` а дальше мне опять даёт возможность ввести

Похоже я просто не выкупил суть задумки. Когда я это писал, то хотел сказать, что нет смысла синхронизировать два процесса, потому что получается почти синхронная программа. Да и по-моему поведение без синхронизации тоже прикольное)

Diman- Автор вопроса
Oman
Похоже я просто не выкупил суть задумки. Когда я э...

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

Похожие вопросы

Обсуждают сегодня

Господа, а что сейчас вообще с рынком труда на делфи происходит? Какова ситуация?
Rꙮman Yankꙮvsky
29
А вообще, что может смущать в самой Julia - бы сказал, что нет единого стандартного подхода по многим моментам, поэтому многое выглядит как "хаки" и произвол. Короче говоря, с...
Viktor G.
2
30500 за редактор? )
Владимир
47
а через ESC-код ?
Alexey Kulakov
29
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
14
Добрый день! Скажите пожалуйста, а какие программы вы бы рекомендовали написать для того, чтобы научиться управлять памятью? Можно написать динамический массив, можно связный ...
Филипп
7
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
Ребят в СИ можно реализовать ООП?
Николай
33
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
Карта сайта