Forum: Ruby-Gnome 2 gtk threading priority

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
8e6374c0ef7b66942f34798e31edf014?d=identicon&s=25 Dobai-Pataky Bálint (Guest)
on 2009-02-13 07:20
(Received via mailing list)
hi,

i have a TCP communication in a background thread,
and want to pulse a progressbar while that is going on,
with the mutexed Gtk.timeout_add threading method,
i even tried to run `while Gtk.events_pending? do
Gtk.main_iteration_do(false);end` in it,
but the problem is, i guess, my background thread has higher priority
than Gtk's main loop.
the progress is not moving smoothly, it's stuck for a while, then it
pulses too fast, than stuck again.
the question is: can i increase the priority where gtk is run? (i guess
it's main loop)

thanks in advice
balint
C838db9af1d90a87a828ecad8556b804?d=identicon&s=25 Guillaume Cottenceau (Guest)
on 2009-02-13 09:31
(Received via mailing list)
On Fri, Feb 13, 2009 at 7:19 AM, Dobai-Pataky Bálint <dpblnt@gmail.com>
wrote:
> too fast, than stuck again.
> the question is: can i increase the priority where gtk is run? (i guess it's
> main loop)

Can you post the program?

I think the priority is not a problem. Gtk is most of the time stuck
waiting for IO (X event) and your network connection should also be
most of the time stuck waiting for IO (bytes to read or write). It's
possible that your network connection is seeing only significant
portions of progress each time, especially if data to transfer is
small (TCP packeting and/or kernel buffering) or if large parts of
data are produced at once.

--
Guillaume Cottenceau - http://zarb.org/~gc/
8616a8bf5c9ac0db67ac26f89d3b06b6?d=identicon&s=25 Mike Charlton (Guest)
on 2009-02-13 10:13
(Received via mailing list)
Personally, I've had a lot of trouble with threads and
the progress bar.  Probably it can be made to work, but
I found that I could never get things to work the way I
wanted to.

What I did is get rid of the thread.  Most of the time
in an interactive program, threads are not necessary.
Instead use a kind of reactor pattern using the main Gtk loop.

http://en.wikipedia.org/wiki/Reactor_pattern

Depending on what you need to do there are several
ways to go about it.  As an example, I'm parsing a very
large file.  It takes about 8 seconds to parse, so I want
a progress bar.  I simply put my file parsing code
into the main loop using Gtk::add_idle.

Every time the main loop is idle it runs my code
which parses about 1000 lines.  When the file
is finished, the code removes itself from the idle
loop.  This technique will almost always give
better performance than a thread, and if you
keep the amount of work per iteration small,
the UI will always be predictably responsive.

Depending on what you're doing, this may or may
not work directly for you.  For instance, as long
as you're doing TCP networking, you aren't going
to drop packets, so it's a great technique.  Simply
read a small chunk (if it's available) each time.

Generally speaking, it's always best to avoid threading
unless you absolutely need fine grained concurrency.


           MikeC

P.S. It may not be completely obvious why this
is a variant of the reactor pattern.  But think
of the addition and subtraction of the idle method
as a "signal".  Also think of the variable showing
the amount of data read in as a "signal".  You
could actually code it that way (and it's a good idea
if you have a complex situation), but for something
simple like reading data from a TCP stream, you
don't have to write so much code :-).
C838db9af1d90a87a828ecad8556b804?d=identicon&s=25 Guillaume Cottenceau (Guest)
on 2009-02-13 11:04
(Received via mailing list)
On Fri, Feb 13, 2009 at 10:13 AM, Mike Charlton <mikekchar@gmail.com>
wrote:
> Personally, I've had a lot of trouble with threads and
> the progress bar.  Probably it can be made to work, but

http://pastebin.ca/1335889 (or
http://zarb.org/~gc/t/threaded_progress.rb)

--
Guillaume Cottenceau - http://zarb.org/~gc/
8e6374c0ef7b66942f34798e31edf014?d=identicon&s=25 Dobai-Pataky Balint (Guest)
on 2009-02-13 16:59
(Received via mailing list)
thanks for your answer,

i'm attaching a bit modified sleeping scrip.
if main loop is sleeping or overloaded with io(which i can't demonstrate
in a sample script i'm afraid)
this is not my real life issue.
that would be running methods in a drb server, whose connection can be
slow, and that also halts the progress.
C838db9af1d90a87a828ecad8556b804?d=identicon&s=25 Guillaume Cottenceau (Guest)
on 2009-02-14 00:06
(Received via mailing list)
> b.signal_connect('clicked'){
>                p "begin"
>                #sleep 1
>                1000.times{sleep 0.001}

if by sleeping you expect to "give hand" to the other thread for
updating the pulse, you're misleaded. the purpose of my approach is to
delay/accumulate the gtk calls in a queue, and these calls will be
flushed next time gtk calls the timeout block; but gtk cannot call the
timeout block by interrupting the processing of the still currently
running clicked callback (gtk doesn't do scheduling at all in the
sense of interrupting running stuff), it will be called only after
your clicked callback is over, so basically what you're doing is
accumulating a lot of "pb.pulse" calls, which will all get flushed at
once when your clicked callback is finished. effectively, your
progressbar is frozen for one second.

the purpose of the threading model in programs is to use other threads
for long running stuff, here you're doing the opposite and it seems
you're defeating the original purpose. in your UI callbacks, you
should do UI stuff (fast things), not processing stuff (you should
exactly do them from another thread, for example your clicked callback
may send a message to the other thread (or start a new thread)
indicating what processing to do).

--
Guillaume Cottenceau - http://zarb.org/~gc/
8e6374c0ef7b66942f34798e31edf014?d=identicon&s=25 Dobai-Pataky Bálint (Guest)
on 2009-02-14 19:47
(Received via mailing list)
On 02/14/2009 01:05 AM, Guillaume Cottenceau wrote:
> timeout block by interrupting the processing of the still currently
> running clicked callback (gtk doesn't do scheduling at all in the
> sense of interrupting running stuff), it will be called only after
> your clicked callback is over, so basically what you're doing is
> accumulating a lot of "pb.pulse" calls, which will all get flushed at
> once when your clicked callback is finished. effectively, your
> progressbar is frozen for one second.
>
yes, i know that.
> the purpose of the threading model in programs is to use other threads
> for long running stuff, here you're doing the opposite and it seems
> you're defeating the original purpose. in your UI callbacks, you
> should do UI stuff (fast things), not processing stuff (you should
> exactly do them from another thread, for example your clicked callback
> may send a message to the other thread (or start a new thread)
> indicating what processing to do).
>
>
yes, it crossed my mind, and this is what i do:
on user action i start a thread, and do the drb communications in that
thread, but that blocks my pulse, like this sleep example does.
my original question was abount priority of threads, to increase the gtk
main loop's priority, or decrase the drb thread's (which i don't know
how, could i, i guess it's network io).

thank you for your answer.
balint
This topic is locked and can not be replied to.