0

After looking at the KeyboardInterrupt to exit out of a multithreaded script I was wondering if it's possible to use the up and down keys on a keyboard to increase/decrease the number of threads being used? This would hopefully happen the same manner as KeyboardInterrupt so that it could happen at anytime. Is something like this possible or is there another method that would be better suited for this?

def do_something(input_file, threads):
concurrent = threads
l = read_csv(input_file)

for i in range(concurrent):
    t = Thread(target=create_accounts)
    t.daemon = True
    t.start()
try:
    for account in l:
        q.put(account)
    q.join()
except KeyboardInterrupt:
    sys.exit(1)

if __name__ == '__main__':

    threads = 1
    q = Queue(threads * 2)
    do_something('test.csv', threads)
Jeff
  • 180
  • 1
  • 11

1 Answers1

1

A KeyboardInterrupt is a special thing. On Unix, Python basically lets the terminal turn the ^C into a SIGINT signal, and it installs a signal handler for SIGINT that raises an exception. On Windows, it's a little more complicated, but the same basic idea. Ordinary keypresses won't interrupt your code.

But you can just dedicate a thread to listening to the keyboard. Your main thread doesn't seem to be doing anything useful; if it is, kick that work off to a background thread. Then your main thread can just sit around waiting for keyboard input.

But… how do you wait for keyboard input? That's the tricky part. Normally, on most platforms, input is line-buffered. And the arrow keys already have a special meaning, like cycling through the history of past entries.

You can do this at the low level by using Console I/O on Windows, termios on Unix), and learning the whole messy business about character codes so you can actually identify the arrow keys. But you'll probably find it a lot easier to use a higher-level wrapper. There are all kinds of choices, ranging from things like getch and consoleio up to PyGame or Qt; search around PyPI.

abarnert
  • 354,177
  • 51
  • 601
  • 671
  • To get an idea of how much fun this is to do at the lowest level, [here](http://pastebin.com/hKsyp3Vq) is a simple program (Python 3.4, Unix-only) that reads your characters until you hit return, and then shows the up and down arrows you pressed. If you think it's hideous, well, that's why you want a higher-level wrapper. :) – abarnert May 05 '15 at 23:34
  • What would you recommend for a clean way to use the main thread to wait for keyboard input? the main hope it to be able to input something to increase the number of threads, but I feel like this could be useful to any multithreading app I have. You're response has peaked my curiosity. Thanks for the info. – Jeff May 06 '15 at 03:05
  • @Jeff: Do you need to be cross-platform? Because in my experience, there are a lot more good Windows-only and Unix-only simple console input libraries than good cross-platform ones. But I don't know the current state of the art for either; you'd probably have to dig around on PyPI yourself. – abarnert May 06 '15 at 03:13
  • I typically use these type of scripts on windows to a lot of bulk rest api calls. So this wouldn't need to be cross platform. – Jeff May 06 '15 at 03:14
  • @Jeff: OK, on Windows… it's been a while, but from what I remember, it's actually not quite as horrible to just use what's in the stdlib. From a quick search, [this answer](http://stackoverflow.com/a/15313849/908494) seems like decent sample code for reading arrow keys. – abarnert May 06 '15 at 03:26
  • @Jeff: But meanwhile, are you sure you don't want to just hack up a simple Tkinter GUI? It may seem like "overkill", but if it's less work and easier to debug and maintain… – abarnert May 06 '15 at 03:26