Thread overview |
---|
October 03, 2017 non-block reading from pipe stdout | ||||
---|---|---|---|---|
| ||||
Hello. I run program through std.process.pipeShell and want to read from it stdout in loop. How do this non-blocking? I try int fd = p.stdout.fileno; int flags = fcntl(fd, F_GETFL, 0); flags |= O_NONBLOCK; fcntl(fd, F_SETFL, flags); but get error "Resource temporarily unavailable". |
October 03, 2017 Re: non-block reading from pipe stdout | ||||
---|---|---|---|---|
| ||||
Posted in reply to Oleg B | On Tuesday, 3 October 2017 at 00:22:28 UTC, Oleg B wrote:
> but get error "Resource temporarily unavailable".
You get EAGAIN because there is no data available at the time of reading.
From the manpage of read:
ERRORS
EAGAIN Non-blocking I/O has been selected using O_NONBLOCK and no data
was immediately available for reading.
|
October 03, 2017 Re: non-block reading from pipe stdout | ||||
---|---|---|---|---|
| ||||
Posted in reply to kdevel | On Tuesday, 3 October 2017 at 10:45:21 UTC, kdevel wrote:
> On Tuesday, 3 October 2017 at 00:22:28 UTC, Oleg B wrote:
>> but get error "Resource temporarily unavailable".
>
> You get EAGAIN because there is no data available at the time of reading.
>
> From the manpage of read:
>
> ERRORS
> EAGAIN Non-blocking I/O has been selected using O_NONBLOCK and no data
> was immediately available for reading.
And I can't check this without using exception handling?
|
October 03, 2017 Re: non-block reading from pipe stdout | ||||
---|---|---|---|---|
| ||||
Posted in reply to kdevel | On Tuesday, 3 October 2017 at 10:45:21 UTC, kdevel wrote: > On Tuesday, 3 October 2017 at 00:22:28 UTC, Oleg B wrote: >> but get error "Resource temporarily unavailable". > > You get EAGAIN because there is no data available at the time of reading. > > From the manpage of read: > > ERRORS > EAGAIN Non-blocking I/O has been selected using O_NONBLOCK and no data > was immediately available for reading. I found only one way: C-style auto pp = pipeShell(updaterScriptCommand, Redirect.all, null, Config.none, workDir); import core.sys.posix.unistd : read; import core.stdc.errno; import core.sys.posix.fcntl; int fd = pp.stdout.fileno; int flags = fcntl(fd, F_GETFL, 0); flags |= O_NONBLOCK; fcntl(fd, F_SETFL, flags); // C-style setting file config char[256] buf; while (!tryWait(pp.pid).terminated) { auto cnt = read(fd, buf.ptr, buf.length); // C-style reading if (cnt == -1 && errno == EAGAIN) // C-style error checking yield(); else if (cnt > 0) { doSomething(buf[0..cnt]); yield(); } } |
October 03, 2017 Re: non-block reading from pipe stdout | ||||
---|---|---|---|---|
| ||||
Posted in reply to Oleg B | On Tuesday, 3 October 2017 at 11:36:28 UTC, Oleg B wrote:
>> EAGAIN Non-blocking I/O has been selected using O_NONBLOCK and no data
>> was immediately available for reading.
>
> And I can't check this without using exception handling?
Your programm shall not read before data is available. Use core.sys.posix.sys.select to check if read would block on a blocking socket.
|
October 03, 2017 Re: non-block reading from pipe stdout | ||||
---|---|---|---|---|
| ||||
Posted in reply to Oleg B | On Tuesday, 3 October 2017 at 12:20:09 UTC, Oleg B wrote:
> while (!tryWait(pp.pid).terminated)
> {
> auto cnt = read(fd, buf.ptr, buf.length); // C-style reading
> if (cnt == -1 && errno == EAGAIN) // C-style error checking
> yield();
> else if (cnt > 0)
> {
> doSomething(buf[0..cnt]);
> yield();
> }
> }
IMHO a program should sleep (consume 0 CPU time and 0 energy) if there is nothing to process. This is best accomplished by not polling on a file descriptor in order to check if data has arrived. If your program must yield() there's probably something wrong with the design. I would suggest you put all the filedescriptors into a fd_set an then select(3) on the set.
|
October 03, 2017 Re: non-block reading from pipe stdout | ||||
---|---|---|---|---|
| ||||
Posted in reply to kdevel | On Tuesday, 3 October 2017 at 12:32:43 UTC, kdevel wrote:
> IMHO a program should sleep (consume 0 CPU time and 0 energy) if there is nothing to process. This is best accomplished by not polling on a file descriptor in order to check if data has arrived. If your program must yield() there's probably something wrong with the design. I would suggest you put all the filedescriptors into a fd_set an then select(3) on the set.
Programs based on fibers can't sleep while wait data and it's not a design problem.
|
Copyright © 1999-2021 by the D Language Foundation