[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Question regarding threads and I/O

Michael W. Ryder

12/17/2006 11:51:00 PM

I am a veteran programmer but still am trying to learn Ruby. In the
language I have been using for over 25 years input has an option to
terminate after x number of seconds, something that seems to be missing
in Ruby. I use this ability to log off sessions when the user leaves
the computer for a time along with other purposes.
Is it possible in Ruby to use two threads for input, one for reading
from the selected source and the second that would terminate the first
thread if it hadn't completed in the specified amount of time? The main
program would start the first thread and feed the PID to the second
thread along with the number of seconds, or milliseconds, to sleep. The
second thread would then see if the first thread is still alive when it
wakes up and if so terminate it. Either way the second thread would
exit after the number of seconds given.
30 Answers

Logan Capaldo

12/18/2006 12:33:00 AM

0

On Mon, Dec 18, 2006 at 08:55:10AM +0900, Michael W. Ryder wrote:
> I am a veteran programmer but still am trying to learn Ruby. In the
> language I have been using for over 25 years input has an option to
> terminate after x number of seconds, something that seems to be missing
> in Ruby. I use this ability to log off sessions when the user leaves
> the computer for a time along with other purposes.
> Is it possible in Ruby to use two threads for input, one for reading
> from the selected source and the second that would terminate the first
> thread if it hadn't completed in the specified amount of time? The main
> program would start the first thread and feed the PID to the second
> thread along with the number of seconds, or milliseconds, to sleep. The
> second thread would then see if the first thread is still alive when it
> wakes up and if so terminate it. Either way the second thread would
> exit after the number of seconds given.
Check out Timeout in the standard lib.
http://www.ruby-doc.org/stdlib/libdoc/timeout/rdoc/...

greg

12/18/2006 1:08:00 AM

0

also, try the highline gem for help in dealing with input in general

Timeout:timeout creates a new thread with a time limit. Is would not
be to hard to hack it up to make a way to be able to keep reseting that
timer if you didn't want the overhead of continually creating new
threads.
One approach would be to implement a rescue and then retry if you have
received input. Here is my quick attempt. The thread which calls
timeout is responsible to keep setting Thread.current[:timeout] = false
whenever it receives input

def timeout(sec, exception=Error)
return yield if sec == nil or sec.zero?
raise ThreadError, "timeout within critical session" if
Thread.critical
begin
x = Thread.current
y = Thread.start {
begin
until x[:timeout]
x[:timeout] = true
sleep sec
end
x.raise exception, "execution expired" if x.alive?
end
}
yield sec
# return true
ensure
y.kill if y and y.alive?
end
end


Thread.abort_on_exception = true


Michael W. Ryder

12/18/2006 1:41:00 AM

0

Logan Capaldo wrote:
> On Mon, Dec 18, 2006 at 08:55:10AM +0900, Michael W. Ryder wrote:
>> I am a veteran programmer but still am trying to learn Ruby. In the
>> language I have been using for over 25 years input has an option to
>> terminate after x number of seconds, something that seems to be missing
>> in Ruby. I use this ability to log off sessions when the user leaves
>> the computer for a time along with other purposes.
>> Is it possible in Ruby to use two threads for input, one for reading
>> from the selected source and the second that would terminate the first
>> thread if it hadn't completed in the specified amount of time? The main
>> program would start the first thread and feed the PID to the second
>> thread along with the number of seconds, or milliseconds, to sleep. The
>> second thread would then see if the first thread is still alive when it
>> wakes up and if so terminate it. Either way the second thread would
>> exit after the number of seconds given.
> Check out Timeout in the standard lib.
> http://www.ruby-doc.org/stdlib/libdoc/timeout/rdoc/...
>

Maybe I am missing something here but it doesn't seem to work for me. I
have the following simple program:

require 'timeout'
foo = nil
status = Timeout::timeout(5) {
foo = gets()
}
puts (foo)

If I enter something, say 123, then the program displays the 123 as
expected. If I just wait it sits there until I enter something which is
not what I want. I want the input to terminate and display that foo is
'nil'. For some reason testing the value of status shows that it is the
same as the input, but this may not be relevant to the problem.

Joel VanderWerf

12/18/2006 2:19:00 AM

0

Michael W. Ryder wrote:
> Maybe I am missing something here but it doesn't seem to work for me. I
> have the following simple program:
>
> require 'timeout'
> foo = nil
> status = Timeout::timeout(5) {
> foo = gets()
> }
> puts (foo)
>
> If I enter something, say 123, then the program displays the 123 as
> expected. If I just wait it sits there until I enter something which is
> not what I want. I want the input to terminate and display that foo is
> 'nil'. For some reason testing the value of status shows that it is the
> same as the input, but this may not be relevant to the problem.

That's a problem with the combination of the msvc-based ruby on windows
and gets and threads (Timeout uses a thread). There was a discussion in
the ruby-talk list with subject "Thread and sleep" a few days ago.

--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Logan Capaldo

12/18/2006 2:34:00 AM

0

On Mon, Dec 18, 2006 at 10:40:05AM +0900, Michael W. Ryder wrote:
> Maybe I am missing something here but it doesn't seem to work for me. I
> have the following simple program:
>
> require 'timeout'
> foo = nil
> status = Timeout::timeout(5) {
> foo = gets()
> }
> puts (foo)
>
> If I enter something, say 123, then the program displays the 123 as
> expected. If I just wait it sits there until I enter something which is
> not what I want. I want the input to terminate and display that foo is
> 'nil'. For some reason testing the value of status shows that it is the
> same as the input, but this may not be relevant to the problem.
It works for me (well actually timeout throws an exception when the time
runs out, doesn't just baort gracefully, but that's what it's supposed
to do.)

What platform are you on?

Michael W. Ryder

12/18/2006 3:00:00 AM

0

Logan Capaldo wrote:
> On Mon, Dec 18, 2006 at 10:40:05AM +0900, Michael W. Ryder wrote:
>> Maybe I am missing something here but it doesn't seem to work for me. I
>> have the following simple program:
>>
>> require 'timeout'
>> foo = nil
>> status = Timeout::timeout(5) {
>> foo = gets()
>> }
>> puts (foo)
>>
>> If I enter something, say 123, then the program displays the 123 as
>> expected. If I just wait it sits there until I enter something which is
>> not what I want. I want the input to terminate and display that foo is
>> 'nil'. For some reason testing the value of status shows that it is the
>> same as the input, but this may not be relevant to the problem.
> It works for me (well actually timeout throws an exception when the time
> runs out, doesn't just baort gracefully, but that's what it's supposed
> to do.)
>
> What platform are you on?
>

Windows XP Pro, which I guess is part of the problem. The problem I
have with Ruby is that I know it is possible to get this to work in
other languages, BBX (Business Basic) for example. It may be that
because BBX did not use Microsoft compilers, it has been out longer than
Microsoft has existed, that it doesn't have some limitations built into
the Microsoft compilers. This of course raises the question is there a
free compiler, such as gcc, which could compile Ruby without the thread
lock problem?

Michael W. Ryder

12/18/2006 3:06:00 AM

0

Joel VanderWerf wrote:
> Michael W. Ryder wrote:
>> Maybe I am missing something here but it doesn't seem to work for me.
>> I have the following simple program:
>>
>> require 'timeout'
>> foo = nil
>> status = Timeout::timeout(5) {
>> foo = gets()
>> }
>> puts (foo)
>>
>> If I enter something, say 123, then the program displays the 123 as
>> expected. If I just wait it sits there until I enter something which
>> is not what I want. I want the input to terminate and display that
>> foo is 'nil'. For some reason testing the value of status shows that
>> it is the same as the input, but this may not be relevant to the problem.
>
> That's a problem with the combination of the msvc-based ruby on windows
> and gets and threads (Timeout uses a thread). There was a discussion in
> the ruby-talk list with subject "Thread and sleep" a few days ago.
>

I read that thread which was why I was wondering if one could use two
threads, one for the gets, and one to terminate that thread after a
period of time if the first thread hadn't already gotten input and
terminated. I know that most non-Microsoft based Operating Systems
don't have this problem but as Microsoft has the majority of the market
programs have to be able to work on their OS. The language I have been
using for over 25 years works identically on a very large number of
platforms from PCs to mainframes so I would think Ruby would be able to
do the same, if not today then in the near future.

Logan Capaldo

12/18/2006 3:43:00 AM

0

On Mon, Dec 18, 2006 at 12:00:06PM +0900, Michael W. Ryder wrote:
> Logan Capaldo wrote:
> >On Mon, Dec 18, 2006 at 10:40:05AM +0900, Michael W. Ryder wrote:
> >>Maybe I am missing something here but it doesn't seem to work for me. I
> >>have the following simple program:
> >>
> >> require 'timeout'
> >> foo = nil
> >> status = Timeout::timeout(5) {
> >> foo = gets()
> >> }
> >> puts (foo)
> >>
> >>If I enter something, say 123, then the program displays the 123 as
> >>expected. If I just wait it sits there until I enter something which is
> >>not what I want. I want the input to terminate and display that foo is
> >>'nil'. For some reason testing the value of status shows that it is the
> >>same as the input, but this may not be relevant to the problem.
> >It works for me (well actually timeout throws an exception when the time
> >runs out, doesn't just baort gracefully, but that's what it's supposed
> >to do.)
> >
> >What platform are you on?
> >
>
> Windows XP Pro, which I guess is part of the problem. The problem I
> have with Ruby is that I know it is possible to get this to work in
> other languages, BBX (Business Basic) for example. It may be that
> because BBX did not use Microsoft compilers, it has been out longer than
> Microsoft has existed, that it doesn't have some limitations built into
> the Microsoft compilers. This of course raises the question is there a
> free compiler, such as gcc, which could compile Ruby without the thread
> lock problem?
I believe the other thread established that this kind of code works in
Cygwin and msys built rubies.

Robert Klemme

12/20/2006 8:08:00 AM

0

On 18.12.2006 03:59, Michael W. Ryder wrote:
> Logan Capaldo wrote:
>> What platform are you on?
>
> Windows XP Pro, which I guess is part of the problem. The problem I
> have with Ruby is that I know it is possible to get this to work in
> other languages, BBX (Business Basic) for example. It may be that
> because BBX did not use Microsoft compilers, it has been out longer than
> Microsoft has existed, that it doesn't have some limitations built into
> the Microsoft compilers. This of course raises the question is there a
> free compiler, such as gcc, which could compile Ruby without the thread
> lock problem?

You can use cygwin's Ruby - this works as expected for me on a Win XP
Home (and I guess also Pro):

Robert@Babelfish2 ~
$ uname -a
CYGWIN_NT-5.1 Babelfish2 1.5.21(0.156/4/2) 2006-07-30 14:21 i686 Cygwin

Robert@Babelfish2 ~
$ ruby -v
ruby 1.8.5 (2006-08-25) [i386-cygwin]

Robert@Babelfish2 ~
$ cat x.rb
require 'timeout'
foo = nil
status = Timeout::timeout(5) {
foo = gets()
}
puts (foo)


Robert@Babelfish2 ~
$ ruby x.rb
/usr/lib/ruby/1.8/timeout.rb:54: execution expired (Timeout::Error)
from /usr/lib/ruby/1.8/timeout.rb:56:in `timeout'
from x.rb:3

Robert@Babelfish2 ~
$ ruby x.rb
12345
12345

I personally prefer cygwin on Windows boxes anyway because you have a
nice shell, environment etc.

Kind regards

robert

Michael W. Ryder

12/20/2006 9:51:00 PM

0

Robert Klemme wrote:
> On 18.12.2006 03:59, Michael W. Ryder wrote:
>> Logan Capaldo wrote:
>>> What platform are you on?
>>
>> Windows XP Pro, which I guess is part of the problem. The problem I
>> have with Ruby is that I know it is possible to get this to work in
>> other languages, BBX (Business Basic) for example. It may be that
>> because BBX did not use Microsoft compilers, it has been out longer
>> than Microsoft has existed, that it doesn't have some limitations
>> built into the Microsoft compilers. This of course raises the
>> question is there a free compiler, such as gcc, which could compile
>> Ruby without the thread lock problem?
>
> You can use cygwin's Ruby - this works as expected for me on a Win XP
> Home (and I guess also Pro):
>
> Robert@Babelfish2 ~
> $ uname -a
> CYGWIN_NT-5.1 Babelfish2 1.5.21(0.156/4/2) 2006-07-30 14:21 i686 Cygwin
>
> Robert@Babelfish2 ~
> $ ruby -v
> ruby 1.8.5 (2006-08-25) [i386-cygwin]
>
> Robert@Babelfish2 ~
> $ cat x.rb
> require 'timeout'
> foo = nil
> status = Timeout::timeout(5) {
> foo = gets()
> }
> puts (foo)
>
>
> Robert@Babelfish2 ~
> $ ruby x.rb
> /usr/lib/ruby/1.8/timeout.rb:54: execution expired (Timeout::Error)
> from /usr/lib/ruby/1.8/timeout.rb:56:in `timeout'
> from x.rb:3
>
> Robert@Babelfish2 ~
> $ ruby x.rb
> 12345
> 12345
>
> I personally prefer cygwin on Windows boxes anyway because you have a
> nice shell, environment etc.
>
> Kind regards
>
> robert

I just tried this on Cygwin using Ruby 1.8.4 and still have the same
problem I had with the Windows version. It still waits for I/O and
status is the same as the input. Neither is what I am looking for.