From: William Morgan Date: 2005-02-13T02:32:39+09:00 Subject: curses, ncurses, threads and non-blocking getch Hello all. It looks like non-blocking getch (i.e. when nodelay = 1) with Ruby's standard curses library blocks when there are other Threads running. Once the other Thread dies, it resumes non-blocking operation once a key is pressed. With the ncurses library, this problem doesn't happen. I'm not a curses/ncurses expert, so maybe I'm doing something wrong. Here's the code: require "curses" begin Curses.init_screen Curses.noecho Curses.stdscr.nodelay = 1 start = Time.now Thread.new { sleep 5; } while true Curses.stdscr.setpos(5, 5) Curses.stdscr.addstr("#{(Time.now - start).round} waiting for input...") Curses.refresh x = Curses.stdscr.getch Curses.stdscr.setpos(5, 5) Curses.stdscr.addstr("#{(Time.now - start).round} got: #{x} ") Curses.refresh sleep 0.5 end ensure Curses.echo Curses.close_screen end You'll see that getch blocks ("waiting for input" is displayed) until after the first five seconds, when the thread dies. Then as soon as you press a key, getch is back in non-blocking mode. If you remove the Thread.new call, everything works as it should. This is on ruby 1.8.2 (2005-01-10) [i386-linux]. For reference, here's the equivalent Ncurses code, which works fine: require "ncurses" begin Ncurses.initscr Ncurses.noecho Ncurses.stdscr.nodelay true start = Time.now Thread.new { sleep 5; } while true Ncurses.stdscr.move(5, 5) Ncurses.stdscr.addstr("#{(Time.now - start).round} waiting for input...") Ncurses.refresh x = Ncurses.stdscr.getch Ncurses.stdscr.move(5, 5) Ncurses.stdscr.addstr("#{(Time.now - start).round} got: #{x} ") Ncurses.refresh sleep 0.5 end ensure Ncurses.endwin end -- William