I'm writing a python game-bot where a user needs to send in an input within a certain amount of time.
My current implementation of this is to spawn a new thread that sleeps for that amount of time, then checks if an input has been sent. A nonce is added as the time could run out after another thread starts which would cause the if chatid in user_threads
part to evaluate to true. Should I use this method or is there a better solution to having a timed input (in the sense less likely to fail due to like race conditions).
I've also tried using multiprocessing.Process
but sharing variables to the other process seems to be a lot more cumbersome.
from threading import Thread
from time import time, sleep
from random import randint
user_threads = {}
def timeout(t,r):
while time()-t<5:
sleep(5-time()+t)
if chatid in user_threads:
if user_threads[chatid][3] != r:
return
del user_threads[chatid]
print("Too slow")
def recvans(ans,inp):
if ans==inp:
print("yes")
else:
print("no")
def starttimer(chatid):
r = randint(0,1<<128)
user_threads[chatid] = [None,None,None,r]
user_threads[chatid][2] = ["a"]
P = Thread(target = timeout, args = (time(),r))
user_threads[chatid][0] = P
user_threads[chatid][1] = recvans
P.start()
while True: # simulating user input from different users (here chatid=1)
inp = input()
chatid = 1
if chatid in user_threads:
t, func, args, _ = user_threads[chatid]
if t == None:
print("Please wait")
continue
del user_threads[chatid]
args += [inp]
func(*args)
continue
if inp == "Start":
starttimer(chatid)
continue
if inp == "Quit":
break
print("Unknown msg")
-
3\$\begingroup\$ Usually is is done via select.select \$\endgroup\$vnp– vnp2020年10月13日 15:29:46 +00:00Commented Oct 13, 2020 at 15:29
1 Answer 1
What @vnp said. Fundamentally,
input
usesstdin
;stdin
can be interpreted as a file handle so long as you're not in Windows;select
can wait for data availability on such handles.
There's a lot of internet help on this topic, including https://stackoverflow.com/a/3471853/313768 ; to quote the solution there:
import sys from select import select timeout = 10 print "Enter something:", rlist, _, _ = select([sys.stdin], [], [], timeout) if rlist: s = sys.stdin.readline() print s else: print "No input. Moving on..."
-
\$\begingroup\$ ahh ic this looks way cleaner for my case since I'm using this in context of a game which receives http(s) requests is there a similar way to do this? \$\endgroup\$Ariana– Ariana2020年10月14日 13:08:46 +00:00Commented Oct 14, 2020 at 13:08