How to stop a process

Hi all,

I write a small GUI/Tk with three buttons: start, stop, exit.

I can associate “start” and “exit” to command like these;

command{start}

command {exit}

They do what I expect. But when I write this line in the script
command{stop}, I get the following messsage:

NameError: unknown option ‘stop’ for #<Tk::Button:0x000000044874f8
@path=".w00002"> (deleted widget?)
—< backtrace of Ruby side >-----
C:/Ruby200-x64/lib/ruby/2.0.0/tk.rb:4988:in `rescue in method_missing’

It looks like there is no “stop” method associated with TkButton. So if
I want to stop a running process, which method can I use?

Another question: how to find out what method is available for
TkButton?

Thanks,

Li

You can use “exit”.

Thanks. But if I use ‘exit’, I will stop the process forever and I don’t
want to do that. I just want to stop the process for a while and it
continues when I press it again, kind of flip flop function. or kind of
like next, stop, next,ect

Li CN wrote in post #1147543:

Thanks. But if I use ‘exit’, I will stop the process forever

More precisely you will terminate it.

and I don’t
want to do that. I just want to stop the process for a while and it
continues when I press it again, kind of flip flop function. or kind of
like next, stop, next,ect

You cannot do that with a graphical application: the process needs to
stay runnable to be able to process the button click events on the
“start” or “exit” button. Otherwise you could use
Process.kill(:SIGSTOP, Process.pid) - but then you need to send “kill
-SIGCONT $pid” from another process.

Since you have a graphical application it is event driven and as long as
there are no events nothing will be done which also means no CPU
resources are used.

Unless, that is, you start background threads. If you do that, you
should modify a global flag in a thread safe way which is queried
regularly by those background threads and which then get blocked. If
you use a condition variable no resources are used and threads will be
blocked (see attached example).

Hi Robert,

After reading some info on threads and multiple tasking, here comes my
solution to stop a process. But there is a bug in my script: when I
press “prev_button”, the script doesn’t print the previous item
immediately. Let say it prints out 1,2,3,4, then I press prev_button.
What I see is the script prints out 4, instead of 3. If I press
prev_button again, it will print 3. If I press prev_button again, it
will print out 2. Similar result is seen if I resume next_button. How
to get rid of this bug?

Also any comments on the codes?

Thanks.

#####################################
require ‘tk’
require ‘win32ole’

def text_to_speech(text,rate=0.4)
speech=WIN32OLE.new(‘SAPI.SpVoice’)
speech.Rate=rate
speech.Volume=100
speech.Speak(text)
end# text_to_speech(text)

root=TkRoot.new()
root.title=“wwwcheckbutton”

new_array=(1…20).to_a
$mycount=0

$button_next=TkButton.new()do
text “Next”
pack()
command proc{
$th_next=Thread.new do
min=$mycount+1
max= new_array.size-1

   new_array[min..max].each do |i|
        puts new_array[$mycount]
        text_to_speech(new_array[$mycount])
        $mycount+=1
        sleep 2
  end
end#thread

} #proc

end

$button_prev=TkButton.new()do
text “Prev”
pack()
command proc{
Thread.kill($th_next)
$th_prev=Thread.new do
puts new_array[$mycount-1]
text_to_speech (new_array[$mycount-1] )
$mycount-=1
end
}
end

$button_stop=TkButton.new()do
text “Stop”
pack()
command proc{
Thread.kill($th_next)
Thread.kill($th_prev) if $th_prev
}
end

Tk.mainloop()

Thank you so much for pointing me to the right direction. I have to read
pickaxe sections on thread and monitor.