Gtk threading priority


#1

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


#2

On Fri, Feb 13, 2009 at 7:19 AM, Dobai-Pataky Bálint removed_email_address@domain.invalid
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 C. - http://zarb.org/~gc/


#3

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 :-).


#4

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.


#5

On Fri, Feb 13, 2009 at 10:13 AM, Mike C. removed_email_address@domain.invalid
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 C. - http://zarb.org/~gc/


#6

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 C. - http://zarb.org/~gc/


#7

On 02/14/2009 01:05 AM, Guillaume C. 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