|
From: sfeam <sf...@us...> - 2018-10-15 06:02:24
|
On Sunday, 14 October 2018 22:41:04 Dima Kogan wrote:
> 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?
It is the intended behaviour.
It may not be ideal but it works.
If you can draw up another scheme using only select I'd be
happy to revisit the code. Maybe the code in the qt
terminal could be used as a guide.
Ethan
|