LINUX.ORG.RU

Лови вывод


0

0

Привет всем!

Помните Сапер спрашивал как ловить STD_OUT потомка ?

Я тут немного поизвращался и написал маленький примерчик,
кстати заняло это не полминуты, а около 25 минут ;-)

Да : как вам нравится syntax-hilighting ????? ;-)

http://www.chat.ru/~yaroslav_v

Ярослав.

Привет !

Да ! 25 МИНУТ == 60*25 секунд !
Сначала я забыл как работает execl(bin_file, arg_0, NULL); забыл
о том, что передается и argv[0]("имя программы")-думал
argv[0]==bin_file, потом искал как прикрепить
file_descriptor к stdio еще смотрел glibc :
закрывает ли fclose() file_descriptor, потом хотел
половить хотя бы некоторые ошибки: perror(err_message);
Далее надо было пойти на freshmeat и найти
программу, которая бы сделала c->html(syntax-hilighted)
и после этого выйти в сеть ( по телефону ) и положить
файл, далее добавить на него ссылку, и, наконец,
кинуть объяву ;-)

25 минут .....

P.S. Если посмотреть на программу, то сразу можно найти
пути оптимизации: убрать else:

if((id=fork()) < 0) {
    return -1;
} else if(!id) { /* else-лишний */
    /* .....
       execl(); */
    return -1;
}
/* ..... */
потом убрать scanf(), далее вообще убрать stdio
потом заменить echo "hello_world" на printf("hello world
");
далее printf заменить на puts(stdout,"hello world");
далее сделать char *buffer -> char buffer[80];
потом посчитать сколько надо на самом деле ловить символов(<80)
......
Оптимизированная версия:

#include <unistd.h>

main()
{
    return write(1, "Hello world
", 12) != 12;
}

Круто ? Это же демонстрационная программа:
надо было наворотить всего туда.

;-)

Ярослав. 

yaroslav_v
() автор топика

Ошибочка SGML.

О! write(1, "hello world(черта-n)", 12); 

yaroslav_v
() автор топика

Народ, ну до чего вы тупой. Ведь я это вам написал (первый) еще Sat Sep 25 14:53:35 1999 MSD ! Чего вам не хватало?

anonymous
()

кайф!

Просто мы кайфуем от составления коротеньких веселых программок ;-)
Мы не тупые, а вдумчивые ;-) 

yaroslav_v
() автор топика

P.P.P.S Кстати там еще надо fscnf поменять на fread, а иначе он по словал читать из потока будет ... а еще поток надо разблокировать (fcntl(...,O_NONBLOCK)). Вот и все, а вот не подскажите как определить длину потока, то есть число байт в нем ?

saper ★★★★★
()

a eto saper znaet tolko tot kto v etot potok pishet i to ne vsegda. poschitay skolko prishlo poka eof ne nastanet ...

master
()

В том то и дело, что ни feof(potok) ни EOF никогда не настанут (или они всегда стоят), короче они или неправильно возникают или вообще не возникают, это было первое, что я пытался сделать, поэтому точно не помню ... Есть еще предложения ?

saper ★★★★★
()

ostaetsya dva varianta - po timeout'u i po poluchenii nekogo simvola/ov libo ya ne ponyal voprosa ?

master
()

Проблема в следующем: поток есть у родителя после отработки потомка (то есть потомка уже нет, а поток со всем его выводом на stdout остался), естественно, что в поток ничего больше не поступает (потомка нет, некому посылать), но видимо из-за того, что это был stdout или еще чего-то определить конец потока нельзя ...

saper ★★★★★
()

fcntl

Привет всем!
To Saper : Я не понимаю зачем в нашем примере нужно менять атрибуты трубы ?

(fcntl(fd[READ],F_SETFL,O_NONBLOCK),fcntl(fd[WRITE],F_SETFL,O_NONBLOCK))
(from man)O_NONBLOCK: The file is opened in non-blocking mode.
Neither the open nor any subsequent operations on the file
descriptor which is returned will cause the calling process
to wait. ?????  

yaroslav_v
() автор топика

Смерть

Приве всем!

To Saper : может просить дите посылать сигнал перед смертью отцу
(посылается всегда?) и тот бы закрывал fd[READ].

Но если детей несколько, то кого закрывать ?

Если все дети говорят в
один fd , то их надо синхронизировать семафором.

Пусть каждое дите посылает перед смертью СООБЩЕНИЕ отцу с указанием 
воего номера, а отец (int **fd) close(fd[id][READ])

P.S. Saper , ты все не хочешь перейти на pthreads или это уже другая
задача ?

Ярослав. 

yaroslav_v
() автор топика

Меняю я не для fd[READ] и fd[WRITE], а в родителе после завершения работы дитя. Дело в том, что fread если он будет читать последний байт, то на следующем он зависнет (так как читать нечего), поэтому делаем NON_BLOCK и тогда fread вернет нуль, что я и принимаю как окончание потока (это конечно работает, но вот хотелось бы не по байтам все читать, а все сразу в буфер перекинуть). Насчет детей, схема такая:
ГЛАВНЫЙ ПАПА (демон) ->:
-> РОДИТЕЛЬ -> РЕБЕНОК
-> РОДИТЕЛЬ -> РЕБЕНОК
...
-> РОДИТЕЛЬ -> РЕБЕНОК

Надеюсь тебе ясны причины, по которым я использую NONBLOCK ?
А вот еще вопрос: использование pthreads сильно ускорит и сократит память для потомков(РЕБЕНОК) и родителей(всех кроме ГЛАВНОГО) ? Так что сообщения слать не надо, каждый родитель по wait-у обнаружит завершение работы потомка. Кстати на Slackware 4.0 проблем с pthreads не будет, а то они libc5, и когда использую некоторые приложения, они (если компилировались с -lpthread как например xmms или kwave) вылетают с сообщением I/O Trap Error или Segmentation fault - точно не помню (для xmms поставил threads-safe X-libs и все заработало).

saper ★★★★★
()

вывод

УУУУУУУУУх!

Сапер : похоже я притомился - пятый раз читаю твой ответ и не
могу понять: про Slackware ты утверждаешь или спрашиваешь ?
Я могу сказать лишь, что лишь очень специфичные функции libc5
будут отказывать в потоках: например поиск регул. выражения (regex)
СРАЗУ двумя потоками может улететь. Но ведь тебя это не трогает?

О папе: ты имеешь ввиду такое
main()
{
/* ПАПА! */
 for(;;) {
  if(!fork()) {
    execl("/Child"); /* заменяем образ на ./Child - рожаем */
  }
 }
}


/* или */


/* daemon.c */
main()
{
/* ПАПА! */
 for(;;) {
  if(!fork()) {
   execl("./Parent");
  }
 }
}
/* parent.c */
main()
{
/* Родитель */
 if(!fork()) {
  execl("./Child");
 }
 wait();
}

/* ????? */

P.S. Slackware7.0 слышал собрали ..... на glibc-2.x ;-)
P.P.S. Потоки  видимо дадут экономию примерно на 50%(!) 

yaroslav_v
() автор топика

Если тебе все еще интересно, то второй вариант. А вообще спасибо тебе !

saper ★★★★★
()
Ответ на: Смерть от yaroslav_v

прежде чем писать, а тем более читать из пипа, разумно проверить, а живо ли дите (родитель).
Можно так: если kill(pid,0) меньше нуля то оно уже сдохло.
У мене работает.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.