# Newbie question about threads and gets

**URL:** <https://www.ruby-forum.com/t/newbie-question-about-threads-and-gets/51883>\
**Category:** Ruby\
**Created:** [January 8, 2006, 6:18pm UTC](https://www.ruby-forum.com/t/newbie-question-about-threads-and-gets/51883 "2006-01-08T18:18:51Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![jacekolszak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/ccd318/32.png) [@jacekolszak](https://www.ruby-forum.com/u/jacekolszak)\
**Post date:** [January 8, 2006, 6:18pm UTC](https://www.ruby-forum.com/t/newbie-question-about-threads-and-gets/51883/1 "2006-01-08T18:18:51Z")

</div>

Hi everyone…

I’ve a simple question - how can I write an application with two  
threads, where first thread reads the user input. I want both threads to  
run SIMULTANEOUSLY.  
So … here is my code:

a=Thread.new do  
$stdin.gets  
end

b=Thread.new do  
5.times do  
print “b”  
$stdout.flush  
Thread.pass  
end  
end

a.join  
b.join

Unfortunelty “gets” block my whole application - the “b” thread waits  
until user writes something to the stdin. But I want the b thread not  
wait and run at the same time.

Thanks  
Jacek

---

<div class="post-metadata">

**Author:** ![jacekolszak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/ccd318/32.png) [@jacekolszak](https://www.ruby-forum.com/u/jacekolszak)\
**Post date:** [January 8, 2006, 6:49pm UTC](https://www.ruby-forum.com/t/newbie-question-about-threads-and-gets/51883/2 "2006-01-08T18:49:39Z")

</div>

From: “Jacek O.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

> b=Thread.new do  
> Unfortunelty “gets” block my whole application - the “b” thread waits  
> until user writes something to the stdin. But I want the b thread not  
> wait and run at the same time.

This tends to be a problem with Windows ruby. It seems unlikely to be  
resolved until Ruby gets native threads (on the horizon with YARV.)

Here’s how I’ve worked around it. If anyone knows a better way, please  
share:

if RUBY\_PLATFORM =~ /win32/  
require ‘Win32API’  
$win32\_console\_kbhit = Win32API.new(“msvcrt”, “\_kbhit”, [], ‘I’)  
def console\_input\_ready?  
$win32\_console\_kbhit.call != 0  
end  
def nonblocking\_stdin\_gets  
sleep(0.1) until console\_input\_ready?  
$stdin.gets # don’t bother to use getc, it also blocks until user  
hits   
end  
else  
def nonblocking\_stdin\_gets  
$stdin.gets # it just works, on unix  
end  
end

So you can use nonblocking\_stdin\_gets in place of $stdin.gets. It’s an  
imperfect solution, though. It will be nonblocking _until_ the user  
starts  
typing. Then it will block until they hit . (Note, I’ve tried  
doing  
it character-by-character, with $stdin.getc or $stdin.sysread(1), but it  
still blocks until the user hits .) There’s probably a way to  
put  
the windows console into unbuffered mode, which would improve this  
hack (so we could use $stdin.getc in conjunction with  
console\_input\_ready?.)

Anyway, hope this helps . . .

Regards,

Bill

---

<div class="post-metadata">

**Author:** ![jacekolszak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/ccd318/32.png) [@jacekolszak](https://www.ruby-forum.com/u/jacekolszak)\
**Post date:** [January 8, 2006, 6:55pm UTC](https://www.ruby-forum.com/t/newbie-question-about-threads-and-gets/51883/3 "2006-01-08T18:55:42Z")

</div>

Jacek O. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Unfortunelty “gets” block my whole application - the “b” thread waits  
> until user writes something to the stdin. But I want the b thread not  
> wait and run at the same time.
> 
> Thanks  
> Jacek

I’m not sure what you’re up to in the end but I’d start with commenting  
Thread.pass. Ruby normally schedules threads automatically and thus you  
usually don’t need Thread.pass. And btw, you can do $stdout.sync=true -  
which removes the necessity of invoking flush.

Ah, and another note: the first thread blocks the whole app until you  
enter  
something simply because it’s joined on. The main thread won’t exit  
until  
you enter something.

HTH

```
robert

```

---

<div class="post-metadata">

**Author:** ![jacekolszak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/ccd318/32.png) [@jacekolszak](https://www.ruby-forum.com/u/jacekolszak)\
**Post date:** [January 8, 2006, 7:15pm UTC](https://www.ruby-forum.com/t/newbie-question-about-threads-and-gets/51883/4 "2006-01-08T19:15:28Z")

</div>

Bill K. wrote:

> From: “Jacek O.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)
> 
> > b=Thread.new do  
> > Unfortunelty “gets” block my whole application - the “b” thread waits  
> > until user writes something to the stdin. But I want the b thread not  
> > wait and run at the same time.
> 
> This tends to be a problem with Windows ruby. It seems unlikely to be  
> resolved until Ruby gets native threads (on the horizon with YARV.)

Yes… I’m using winxp currently ☹

> Here’s how I’ve worked around it. If anyone knows a better way, please  
> share:
> 
> if RUBY\_PLATFORM =~ /win32/  
> require ‘Win32API’  
> $win32\_console\_kbhit = Win32API.new(“msvcrt”, “\_kbhit”, [], ‘I’)  
> def console\_input\_ready?  
> $win32\_console\_kbhit.call != 0  
> end  
> def nonblocking\_stdin\_gets  
> sleep(0.1) until console\_input\_ready?  
> $stdin.gets # don’t bother to use getc, it also blocks until user  
> hits   
> end  
> else  
> def nonblocking\_stdin\_gets  
> $stdin.gets # it just works, on unix  
> end  
> end
> 
> So you can use nonblocking\_stdin\_gets in place of $stdin.gets. It’s an  
> imperfect solution, though. It will be nonblocking _until_ the user  
> starts  
> typing. Then it will block until they hit . (Note, I’ve tried  
> doing  
> it character-by-character, with $stdin.getc or $stdin.sysread(1), but it  
> still blocks until the user hits .) There’s probably a way to  
> put  
> the windows console into unbuffered mode, which would improve this  
> hack (so we could use $stdin.getc in conjunction with  
> console\_input\_ready?.)
> 
> Anyway, hope this helps . . .
> 
> Regards,
> 
> Bill

Thanks a lot Bill! Maybe it is not a perfect solution, but quite useful  
for me at the moment 🙂

P.S. I’m going to change my os till midnight 😉

---

<div class="post-metadata">

**Author:** ![jacekolszak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/ccd318/32.png) [@jacekolszak](https://www.ruby-forum.com/u/jacekolszak)\
**Post date:** [January 8, 2006, 8:53pm UTC](https://www.ruby-forum.com/t/newbie-question-about-threads-and-gets/51883/5 "2006-01-08T20:53:58Z")

</div>

Jacek O. wrote:

> Robert K. wrote:
> 
> > Jacek O. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> > 
> > > Unfortunelty “gets” block my whole application - the “b” thread waits  
> > > until user writes something to the stdin. But I want the b thread not  
> > > wait and run at the same time.
> > > 
> > > Thanks  
> > > Jacek
> > 
> > I’m not sure what you’re up to in the end but I’d start with commenting  
> > Thread.pass. Ruby normally schedules threads automatically and thus you  
> > usually don’t need Thread.pass. And btw, you can do $stdout.sync=true -  
> > which removes the necessity of invoking flush.
> > 
> > Ah, and another note: the first thread blocks the whole app until you  
> > enter  
> > something simply because it’s joined on. The main thread won’t exit  
> > until  
> > you enter something.
> > 
> > HTH
> > 
> > ```
> > robert
> > 
> > ```
> 
> First of all… thanks for help. I’ve set sync to true and remove  
> Thread.pass. (but as you said these things won’t fix the problem). So  
> I’ve removed _a.join_ call and now everything works! (but wait a second
> 
> - only on my newly installed linux :(, on windows works only with Bill  
> solution)

I don’t know hot it is possible but this code works on windows too :

$stdout.sync=true

a=Thread.new do  
50.times do  
$stdin.gets  
puts “==”+$aaa.to\_s  
end  
end

b=Thread.new do  
10000000000.times do |i|  
$aaa=i  
# Thread.pass - when uncomment this - works on linux only, when  
comment this - works on windows only 🙂  
end

end

b.join

Thanks a lot once again!  
Jacek

---

<div class="post-metadata">

**Author:** ![jacekolszak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/ccd318/32.png) [@jacekolszak](https://www.ruby-forum.com/u/jacekolszak)\
**Post date:** [January 8, 2006, 8:47pm UTC](https://www.ruby-forum.com/t/newbie-question-about-threads-and-gets/51883/6 "2006-01-08T20:47:11Z")

</div>

Robert K. wrote:

> Jacek O. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > Unfortunelty “gets” block my whole application - the “b” thread waits  
> > until user writes something to the stdin. But I want the b thread not  
> > wait and run at the same time.
> > 
> > Thanks  
> > Jacek
> 
> I’m not sure what you’re up to in the end but I’d start with commenting  
> Thread.pass. Ruby normally schedules threads automatically and thus you  
> usually don’t need Thread.pass. And btw, you can do $stdout.sync=true -  
> which removes the necessity of invoking flush.
> 
> Ah, and another note: the first thread blocks the whole app until you  
> enter  
> something simply because it’s joined on. The main thread won’t exit  
> until  
> you enter something.
> 
> HTH
> 
> ```
> robert
> 
> ```

First of all… thanks for help. I’ve set sync to true and remove  
Thread.pass. (but as you said these things won’t fix the problem). So  
I’ve removed _a.join_ call and now everything works! (but wait a second

- only on my newly installed linux :(, on windows works only with Bill  
solution)

Regards  
Jacek

---

<div class="post-metadata">

**Author:** ![jacekolszak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/ccd318/32.png) [@jacekolszak](https://www.ruby-forum.com/u/jacekolszak)\
**Post date:** [January 9, 2006, 11:04am UTC](https://www.ruby-forum.com/t/newbie-question-about-threads-and-gets/51883/7 "2006-01-09T11:04:47Z")

</div>

Jacek O. wrote:

> > > > Jacek  
> > > > until  
> > > > with Bill solution)  
> > > > end
> 
> b.join

Are you aware of the fact that ruby will exit as soon as the main thread  
exits? So your difference might well be timing related.

10:58:20 [source]: ruby -e ‘Thread.new { sleep 1; puts “end” }’  
10:59:22 [source]: ruby -e ‘Thread.new { sleep 1; puts “end” }; sleep 2’  
end  
10:59:28 [source]:

Notice how the first piece doesn’t print? That’s because the main  
thread  
simply exits killing the sleeping first thread.

Again, I don’t know what you’re up to so it’s difficult to provide  
advice  
how to do it right. In your simple example thread a is pointless IMHO -  
you could do that as well in the main thread.

Cheers

```
robert
```

---

<div class="post-metadata">

**Author:** ![jacekolszak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/ccd318/32.png) [@jacekolszak](https://www.ruby-forum.com/u/jacekolszak)\
**Post date:** [January 9, 2006, 8:20pm UTC](https://www.ruby-forum.com/t/newbie-question-about-threads-and-gets/51883/8 "2006-01-09T20:20:16Z")

</div>

Robert K. wrote:

> Jacek O. wrote:
> 
> > > > > Jacek  
> > > > > until  
> > > > > with Bill solution)  
> > > > > end
> > 
> > b.join
> 
> Are you aware of the fact that ruby will exit as soon as the main thread  
> exits?

Yes… I know…

So your difference might well be timing related.

> 10:58:20 [source]: ruby -e ‘Thread.new { sleep 1; puts “end” }’  
> 10:59:22 [source]: ruby -e ‘Thread.new { sleep 1; puts “end” }; sleep 2’  
> end  
> 10:59:28 [source]:
> 
> Notice how the first piece doesn’t print? That’s because the main  
> thread  
> simply exits killing the sleeping first thread.
> 
> Again, I don’t know what you’re up to so it’s difficult to provide  
> advice  
> how to do it right. In your simple example thread a is pointless IMHO -  
> you could do that as well in the main thread.

The problem is with windows - gets command blocks every thread in  
application.  
In my example the b thread is automatically started. In the same time in  
a thread, gets command waits for user input. But in fact, on windows  
platform gets command blocks everything, so nothing is done in “b”  
thread. And I want to write an application which do something in the  
background, and wait for user input at the same time (on windows it’s  
currently impossible ☹ )

Regards  
Jacek
