The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  ВХОД  слежка  RSS
"pipe() + ifstream()"
Вариант для распечатки Архивированная нить - только для чтения! 
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [Проследить за развитием треда]

"pipe() + ifstream()"
Сообщение от stalker emailИскать по авторуВ закладки(??) on 05-Июл-04, 15:57  (MSK)
Народ!
Подскажите как правильно сделать такое:

8<-------
int p[4];
pipe(&p[0]); // в трубу писать
pipe(&p[2]); // из трубы читать

pid = fork();
if(!pid) {
    dup2(p[0],0);
    dup2(p[3],1);
    close(лишние дескрипторы);
    execlp("cat", "cat", 0);
}

ofstream foo(p[1]);
foo << (string)data;
foo.close();

// до сих пор все работает.
// и вот тут хочется что-то типа

ifstream bar(p[2]);
bar >> data;

// как правильно инициализировать поток, чтобы он за раз все данные отдал?

waitpid(pid, .... );

8<---------

ЗС,
Стас


  Рекомендовать в FAQ | Cообщить модератору | Наверх

 Оглавление

Индекс форумов | Темы | Пред. тема | След. тема
Сообщения по теме

1. "pipe() + ifstream()"
Сообщение от SergeiZz Искать по авторуВ закладки on 05-Июл-04, 16:41  (MSK)
>int p[4];
>pipe(&p[0]); // в трубу писать
>pipe(&p[2]); // из трубы читать
>
>pid = fork();
>if(!pid) {
>    dup2(p[0],0);
>    dup2(p[3],1);
Последние две строки зачем?

>    close(лишние дескрипторы);
>    execlp("cat", "cat", 0);
>}
>
>ofstream foo(p[1]);
>foo << (string)data;
>foo.close();
>
>// до сих пор все работает.
>// и вот тут хочется что-то типа
Это работает?
У ofstream (как и у ifstream) нет конструктора с аргументом int!

>как правильно инициализировать поток, чтобы он за раз все данные отдал?
Наверно, нужно использовать именованные каналы (fifo)...

  Рекомендовать в FAQ | Cообщить модератору | Наверх

2. "pipe() + ifstream()"
Сообщение от stalker emailИскать по авторуВ закладки(??) on 05-Июл-04, 16:59  (MSK)
>>int p[4];
>>pipe(&p[0]); // в трубу писать
>>pipe(&p[2]); // из трубы читать
>>
>>pid = fork();
>>if(!pid) {
>>    dup2(p[0],0);
>>    dup2(p[3],1);
>Последние две строки зачем?
>
>>    close(лишние дескрипторы);

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

>>    execlp("cat", "cat", 0);

Конечно, это чушь! :))) реально здесь будет "pnmtopng", при чем, всего будет несколько процессов, завязанных каналами (не хочется "приземлять" данные на файловую систему), а-ля "$ cat data | jpegtopnm | pnmtopng"

>>}
>>
>>ofstream foo(p[1]);
>>foo << (string)data;
>>foo.close();
>>
>>// до сих пор все работает.
>>// и вот тут хочется что-то типа
>Это работает?

Работает, да еще как!!!!

>У ofstream (как и у ifstream) нет конструктора с аргументом int!

Выходит, что есть.... я не лазал в ..stream.h, но, видимо "там" знают про инт... по крайней мере ofstream отрабатывает как надо.

>
>>как правильно инициализировать поток, чтобы он за раз все данные отдал?
>Наверно, нужно использовать именованные каналы (fifo)...

Но ведь на выход все работает! Должно и на вход срабатывать....
Скажу больше, из bar удается считать только 4 байта....

  Рекомендовать в FAQ | Cообщить модератору | Наверх

3. "pipe() + ifstream()"
Сообщение от SergeiZz Искать по авторуВ закладки on 05-Июл-04, 17:12  (MSK)
>если не закрыть, то дочерний процесс может подвиснуть в piperd, ожидая, что
>в один из открытых каналов я буду что-то писать/читать из парент
>процесса, порождая тем самым дедлок на waitpide. По крайней мере, я
>так это понял, потестировав код, не закрывая каналы с одной и
>с другой стороны. Да... теории не хватает....
Это проще можно... Он и должен так себя вести.

>>>    execlp("cat", "cat", 0);
>
>Конечно, это чушь! :))) реально здесь будет "pnmtopng", при чем, всего будет
>несколько процессов, завязанных каналами (не хочется "приземлять" данные на файловую систему),
>а-ля "$ cat data | jpegtopnm | pnmtopng"
fifo имеет только имя в файловой системе, сам он в ядре. Здесь поэтому
без проблем. Если производительность супер важна (что, судя по Вашим
словам, вряд ли), то надо использовать разделяемую память. При записи в
канал данные копируются в ядро и обратно.

>>>ofstream foo(p[1]);
>>>foo << (string)data;
>>>foo.close();
>>>
>>>// до сих пор все работает.
>>>// и вот тут хочется что-то типа
>>Это работает?
>
>Работает, да еще как!!!!
>
>>У ofstream (как и у ifstream) нет конструктора с аргументом int!
>
>Выходит, что есть.... я не лазал в ..stream.h, но, видимо "там" знают
>про инт... по крайней мере ofstream отрабатывает как надо.
Я лазил! Это истика какая-то. Какой компилятор?

>Но ведь на выход все работает! Должно и на вход срабатывать....
Но ведь и придерживаться стандарта то же нужно :)

  Рекомендовать в FAQ | Cообщить модератору | Наверх

4. "pipe() + ifstream()"
Сообщение от stalker emailИскать по авторуВ закладки(??) on 05-Июл-04, 17:24  (MSK)
>>если не закрыть, то дочерний процесс может подвиснуть в piperd, ожидая, что
>>в один из открытых каналов я буду что-то писать/читать из парент
>>процесса, порождая тем самым дедлок на waitpide. По крайней мере, я
>>так это понял, потестировав код, не закрывая каналы с одной и
>>с другой стороны. Да... теории не хватает....
>Это проще можно... Он и должен так себя вести.

А как проще?

еще знаю fcntl( ... ,FD_CLOEXEC) но какая разница где и как его глушить?

>
>>>>    execlp("cat", "cat", 0);
>>
>>Конечно, это чушь! :))) реально здесь будет "pnmtopng", при чем, всего будет
>>несколько процессов, завязанных каналами (не хочется "приземлять" данные на файловую систему),
>>а-ля "$ cat data | jpegtopnm | pnmtopng"
>fifo имеет только имя в файловой системе, сам он в ядре. Здесь
>поэтому
>без проблем. Если производительность супер важна (что, судя по Вашим
>словам, вряд ли), то надо использовать разделяемую память. При записи в
>канал данные копируются в ядро и обратно.

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

>
>>>>ofstream foo(p[1]);
>>>>foo << (string)data;
>>>>foo.close();
>>>>
>>>>// до сих пор все работает.
>>>>// и вот тут хочется что-то типа
>>>Это работает?
>>
>>Работает, да еще как!!!!
>>
>>>У ofstream (как и у ifstream) нет конструктора с аргументом int!
>>
>>Выходит, что есть.... я не лазал в ..stream.h, но, видимо "там" знают
>>про инт... по крайней мере ofstream отрабатывает как надо.
>Я лазил! Это истика какая-то. Какой компилятор?

$g++ -v
Using builtin specs.
gcc version 2.95.4 200220320 [FreeBSD]
$
от себя: FreeBSD 4.7

>
>>Но ведь на выход все работает! Должно и на вход срабатывать....
>Но ведь и придерживаться стандарта то же нужно :)

согласен. Хотя портинг этому проекту врядтли грозит. ;)

  Рекомендовать в FAQ | Cообщить модератору | Наверх

6. "pipe() + ifstream()"
Сообщение от SergeiZz Искать по авторуВ закладки on 08-Июл-04, 13:03  (MSK)
>>>если не закрыть, то дочерний процесс может подвиснуть в piperd, ожидая, что
>>>в один из открытых каналов я буду что-то писать/читать из парент
>>>процесса, порождая тем самым дедлок на waitpide. По крайней мере, я
>>>так это понял, потестировав код, не закрывая каналы с одной и
>>>с другой стороны. Да... теории не хватает....
>>Это проще можно... Он и должен так себя вести.
>
>А как проще?
Тут надо покопаться в формулировке задачки. Если не нужно блокировать
при чтении, но нужно использовать неблокируемое чтение, только и всего.

>производительность не на последнем месте, но мне не хочется изучать кучу графических
>стандартов, чтобы их меж собой тасовать....
>Тем не менее, если есть опыть, пожалуйста поделитесь.
Да там просто всё, например, в Sys V -- shmget() и еже с ним.

>$g++ -v
>Using builtin specs.
>gcc version 2.95.4 200220320 [FreeBSD]
>$
>от себя: FreeBSD 4.7
Ну, про этот реликт надо уточнять, но всё равно -- мистика.

>>>Но ведь на выход все работает! Должно и на вход срабатывать....
>>Но ведь и придерживаться стандарта то же нужно :)
>
>согласен. Хотя портинг этому проекту врядтли грозит. ;)
Даже на gcc-2.96 (для которого точно нет такого конструктора)?

  Рекомендовать в FAQ | Cообщить модератору | Наверх

8. "pipe() + ifstream()"
Сообщение от stalker emailИскать по авторуВ закладки(??) on 08-Июл-04, 13:44  (MSK)
>>>>если не закрыть, то дочерний процесс может подвиснуть в piperd, ожидая, что
>>>>в один из открытых каналов я буду что-то писать/читать из парент
>>>>процесса, порождая тем самым дедлок на waitpide. По крайней мере, я
>>>>так это понял, потестировав код, не закрывая каналы с одной и
>>>>с другой стороны. Да... теории не хватает....
>>>Это проще можно... Он и должен так себя вести.
>>
>>А как проще?
>Тут надо покопаться в формулировке задачки. Если не нужно блокировать
>при чтении, но нужно использовать неблокируемое чтение, только и всего.
>
>>производительность не на последнем месте, но мне не хочется изучать кучу графических
>>стандартов, чтобы их меж собой тасовать....
>>Тем не менее, если есть опыть, пожалуйста поделитесь.
>Да там просто всё, например, в Sys V -- shmget() и еже
>с ним.

а как объяснить внешним утилитам объяснить, что нужно использовать не потоки, а шарную память? Боюсь, не подойдет. fork, pipe и т.п. в данном случае вызваны отсутствием времени на изучение пачки графических стандартов. Если бы знал, полагаю, стринга мне хватило бы.

>
>>$g++ -v
>>Using builtin specs.
>>gcc version 2.95.4 200220320 [FreeBSD]
>>$
>>от себя: FreeBSD 4.7
>Ну, про этот реликт надо уточнять, но всё равно -- мистика.
>
>>>>Но ведь на выход все работает! Должно и на вход срабатывать....
>>>Но ведь и придерживаться стандарта то же нужно :)
>>
>>согласен. Хотя портинг этому проекту врядтли грозит. ;)
>Даже на gcc-2.96 (для которого точно нет такого конструктора)?

не смогу ответить быстро, - у меня его нет. Если хочешь, могу дать исходник для теста.

Кстати, в каком именно ..stream.h искать конструкторы?

  Рекомендовать в FAQ | Cообщить модератору | Наверх

10. "pipe() + ifstream()"
Сообщение от SergeiZz Искать по авторуВ закладки on 16-Июл-04, 18:29  (MSK)
>а как объяснить внешним утилитам объяснить, что нужно использовать не потоки, а
>шарную память? Боюсь, не подойдет. fork, pipe и т.п. в данном
>случае вызваны отсутствием времени на изучение пачки графических стандартов. Если бы
>знал, полагаю, стринга мне хватило бы.
Эх... надо подумать... Так... задача такая: надо вывод cat отправить в
разделяемую память, из которой его прочитать своей программой...
Надо подумать...
Но толку тут мало, потому что cat будет использовать каналы всё равно.
Нужна объектно-ориентированная ОС для подобных задач.

>не смогу ответить быстро, - у меня его нет. Если хочешь, могу
>дать исходник для теста.
Брось на zbl@gmail.ru, но только с бесплатного ящика какого нибудь.
Я на этот адрес спам собираю (для научной работы по прагматическому
анализу), а со спамом вирусы в изобилии приходят, и этот адрес широко
известен среди зараженных машин по всему Миру, так что с него посыпаться
вирусы (для Windoze, естессестно) могут запрасто.

>Кстати, в каком именно ..stream.h искать конструкторы?
А я нашёл, в чём дело. И конструктор нашёл. Но сей час времени нет
рассказать...

  Рекомендовать в FAQ | Cообщить модератору | Наверх

11. "pipe() + ifstream()"
Сообщение от stalker emailИскать по авторуВ закладки(??) on 16-Июл-04, 18:49  (MSK)
>>а как объяснить внешним утилитам объяснить, что нужно использовать не потоки, а
>>шарную память? Боюсь, не подойдет. fork, pipe и т.п. в данном
>>случае вызваны отсутствием времени на изучение пачки графических стандартов. Если бы
>>знал, полагаю, стринга мне хватило бы.
>Эх... надо подумать... Так... задача такая: надо вывод cat отправить в
>разделяемую память, из которой его прочитать своей программой...
>Надо подумать...
>Но толку тут мало, потому что cat будет использовать каналы всё равно.
>
>Нужна объектно-ориентированная ОС для подобных задач.
>
>>не смогу ответить быстро, - у меня его нет. Если хочешь, могу
>>дать исходник для теста.
>Брось на zbl@gmail.ru, но только с бесплатного ящика какого нибудь.
>Я на этот адрес спам собираю (для научной работы по прагматическому
>анализу), а со спамом вирусы в изобилии приходят, и этот адрес широко
>
>известен среди зараженных машин по всему Миру, так что с него посыпаться
>
>вирусы (для Windoze, естессестно) могут запрасто.

исходник дам, но попозже. Не до него сейчас...

>
>>Кстати, в каком именно ..stream.h искать конструкторы?
>А я нашёл, в чём дело. И конструктор нашёл. Но сей час
>времени нет
>рассказать...

Так все-таки есть конструктор с интом?


  Рекомендовать в FAQ | Cообщить модератору | Наверх

12. "pipe() + ifstream()"
Сообщение от Alexander S. SalieFF emailИскать по авторуВ закладки on 17-Июл-04, 20:49  (MSK)
>Так все-таки есть конструктор с интом?

Поточный конструктор вокруг файлового дескриптора - это _depricated_, и производители компилера могут его реализовывать, а могут и забить, 3ю редакцию C++ они при этом не нарушат. Так что, хоть он и есть (конструктор), лучше считать, что его нету.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

13. "pipe() + ifstream()"
Сообщение от stalker emailИскать по авторуВ закладки(??) on 19-Июл-04, 11:51  (MSK)
>>Так все-таки есть конструктор с интом?
>
>Поточный конструктор вокруг файлового дескриптора - это _depricated_, и производители компилера могут
>его реализовывать, а могут и забить, 3ю редакцию C++ они при
>этом не нарушат. Так что, хоть он и есть (конструктор), лучше
>считать, что его нету.

А как тогда сделать поток из pipe?

  Рекомендовать в FAQ | Cообщить модератору | Наверх

14. "pipe() + ifstream()"
Сообщение от stalker emailИскать по авторуВ закладки(??) on 30-Июл-04, 00:38  (MSK)
>>Так все-таки есть конструктор с интом?
>
>Поточный конструктор вокруг файлового дескриптора - это _depricated_, и производители компилера могут
>его реализовывать, а могут и забить, 3ю редакцию C++ они при
>этом не нарушат. Так что, хоть он и есть (конструктор), лучше
>считать, что его нету.

... случайно залез в fstream.h (OpenBSD 3.2: /usr/include/g++)и обнаружил вот такой текст:

class ifstream : public fstreambase, public istream {
  public:
    ifstream() : fstreambase() { }
    ifstream(int fd) : fstreambase(fd) { }
    ifstream(int fd, char *p, int l) : fstreambase(fd, p, l){ } /*Deprecated*/
    ifstream(const char *name, int mode=ios::in, int prot=0664)
        : fstreambase(name, mode | ios::in, prot) { }
    void open(const char *name, int mode=ios::in, int prot=0664)
        { fstreambase::open(name, mode | ios::in, prot); }
};

Обратите внимание на какой именно конструктор косо смотрят.
Выходит, что конструктор с интом прокатывает!?
Во фришном (4.7) дистрибутиве тоже самое...
Где грабли?

  Рекомендовать в FAQ | Cообщить модератору | Наверх

5. "pipe() + ifstream()"
Сообщение от stalker emailИскать по авторуВ закладки(??) on 06-Июл-04, 12:20  (MSK)
>Народ!
>Подскажите как правильно сделать такое:
>
>8<-------
>int p[4];
>pipe(&p[0]); // в трубу писать
>pipe(&p[2]); // из трубы читать
>
>pid = fork();
>if(!pid) {
>    dup2(p[0],0);
>    dup2(p[3],1);
>    close(лишние дескрипторы);
>    execlp("cat", "cat", 0);
>}
>
>ofstream foo(p[1]);
>foo << (string)data;
>foo.close();
>
>// до сих пор все работает.
>// и вот тут хочется что-то типа
>
>ifstream bar(p[2]);
>bar >> data;
>
>// как правильно инициализировать поток, чтобы он за раз все данные отдал?

ответ пришел из маленького справочника, который я купил 10 (!!!) лет назад

string data;
char c;
while (bar >> c) data+=c;

чувствую, что про производительности здесь ждать не приходится ....


>
>
>waitpid(pid, .... );
>
>8<---------
>
>ЗС,
>Стас


  Рекомендовать в FAQ | Cообщить модератору | Наверх

7. "pipe() + ifstream()"
Сообщение от SergeiZz Искать по авторуВ закладки on 08-Июл-04, 13:12  (MSK)
>>// как правильно инициализировать поток, чтобы он за раз все данные отдал?
>
>ответ пришел из маленького справочника, который я купил 10 (!!!) лет назад
>
>
>string data;
>char c;
>while (bar >> c) data+=c;
Здесь я неправильно понял, что значит инициализировать.
Но справочник по-страшному врёт, между прочим:
string buf;
char c= 0;
while( bar.get(c) ) buf+= c;
Не слабая разница, правда?

>чувствую, что про производительности здесь ждать не приходится ....
Нет. С производительностью всё в порядке, по крайней мере, когда не
известно, сколько символов будет прочитано. Опратор добавления символа
к string в libstdc++ реализован грамотно (супротив соответствующему ляпу
в MS VC 6.0).

  Рекомендовать в FAQ | Cообщить модератору | Наверх

9. "pipe() + ifstream()"
Сообщение от stalker emailИскать по авторуВ закладки(??) on 08-Июл-04, 13:51  (MSK)
>>>// как правильно инициализировать поток, чтобы он за раз все данные отдал?
>>
>>ответ пришел из маленького справочника, который я купил 10 (!!!) лет назад
>>
>>
>>string data;
>>char c;
>>while (bar >> c) data+=c;
>Здесь я неправильно понял, что значит инициализировать.
>Но справочник по-страшному врёт, между прочим:
>string buf;
>char c= 0;
>while( bar.get(c) ) buf+= c;
>Не слабая разница, правда?

справочник не врет, просто я сноску там не прочитал. По-ходу, сдвиг отличается от get() тем, что последняя "не глотает" пробелы.... Не проверял, но верю охотно.

В этом была ошибка?


>
>>чувствую, что про производительности здесь ждать не приходится ....
>Нет. С производительностью всё в порядке, по крайней мере, когда не
>известно, сколько символов будет прочитано. Опратор добавления символа
>к string в libstdc++ реализован грамотно (супротив соответствующему ляпу
>в MS VC 6.0).


  Рекомендовать в FAQ | Cообщить модератору | Наверх


Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Пожалуйста, прежде чем написать сообщение, ознакомьтесь с данными рекомендациями.




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру