|
From: Dima K. <gn...@di...> - 2018-10-15 05:41:16
|
sfeam <sf...@us...> writes:
> On Sunday, 14 October 2018 18:25:31 Dima Kogan wrote:
>> I just hit another bug in the same area; a more serious one this time.
>>
>> When I run gnuplot normally with 'pause mouse close', it blocks
>> somewhere, and doesn't waste cycles while we're waiting. In my usage,
>> however, I rarely run gnuplot directly. I almost always use either
>> feedgnuplot (a shell frontend) or gnuplotlib (a plotting interface for
>> numpy in python). At least in the latter case, the 'pause mouse close'
>> works, but gnuplot spins instead of blocking, which wastes CPU
>> resources.
>>
>> I'm attaching a tiny program in python that shows the issue. You should
>> change the GNUPLOT_SRC_DIR definition in that program to point to your
>> source tree. This test program
>>
>> - spawns gnuplot (as a child of the python)
>> - asks it to plot something
>> - "pause mouse close"
>> - "print xxx"
>> - reads gnuplot output until it sees "xxx". This is the most reliable
>> way I've found to let programs talk to gnuplot. If you know of a
>> better synchronization method, please tell me
>>
>> When I run this python program I see gnuplot repeatedly call usleep(10)
>> in X11_waitforinput() in x11.trm. I haven't looked enough at this code
>> path to understand what it's trying to accomplish. It feels like we
>> should never be doing this: all waiting should happen in the select() or
>> something like it.
>
> It is on purpose, wisely chosen or not.
>
>> I also don't understand why I'm hitting this code
>> path in python, but not if I run gnuplot interactively ("gnuplot" and
>> then type in the commands) and not if I run it as a script (put the
>> "plot" and "pause mouse close" into tst.gp, and "gnuplot tst.gp").
>
> This is explained in the comments at x11.trm:894
> /* When taking input from the console, we are willing to wait here */
> /* until the next character is typed. But if input is from a script */
> /* we just want to check for hotkeys or mouse input and then leave */
> /* again without waiting on stdin. */
>
> When the input is from the console we can select on stdin and not spin.
> But if input is from a pipe this will always return immediately unless the
> other end of the pipe does something clever to interlock operations.
OK, I don't fully grok this, but it feels wrong. If I strace the gnuplot
process when running inside python, the spin looks like this:
2482 select(5, [0 4], NULL, NULL, NULL) = 1 (in [0])
2482 nanosleep({tv_sec=0, tv_nsec=10000}, NULL) = 0
2482 select(5, [0 4], NULL, NULL, NULL) = 1 (in [0])
2482 nanosleep({tv_sec=0, tv_nsec=10000}, NULL) = 0
2482 select(5, [0 4], NULL, NULL, NULL) = 1 (in [0])
2482 nanosleep({tv_sec=0, tv_nsec=10000}, NULL) = 0
....
I.e.
- we select(stdin, ipc_back_fd)
- select() returns immediately because there's data available on stdin
- we DON'T read this data
- we sleep a bit
- we select() again
- Since we never read the data select() said was available the first
time, select() returns immediately again
- And we spin
Surely this can't be the intended behavior?
|