Wejście czasowe w Pythonie
Piszę bota do gry w Pythonie, w którym użytkownik musi wysłać dane wejściowe w określonym czasie.
Moja obecna implementacja polega na utworzeniu nowego wątku, który śpi przez ten czas, a następnie sprawdza, czy dane wejściowe zostały wysłane. Dodawana jest wartość jednorazowa, ponieważ czas może upłynąć po uruchomieniu innego wątku, co spowodowałoby, że if chatid in user_threadsczęść została oszacowana jako prawda. Czy powinienem użyć tej metody, czy jest lepsze rozwiązanie, jeśli chodzi o czasowe wejście (w sensie mniej prawdopodobne, że zawiedzie z powodu podobnych warunków wyścigu).
Próbowałem też używać, multiprocessing.Processale udostępnianie zmiennych innemu procesowi wydaje się znacznie bardziej kłopotliwe.
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")
Odpowiedzi
Co powiedział @vnp. Zasadniczo,
inputzastosowaniastdin;stdinmoże być interpretowane jako uchwyt pliku, o ile nie jesteś w systemie Windows;selectmogą czekać na dostępność danych na takich uchwytach.
Istnieje wiele pomocy internetowych na ten temat, w tym https://stackoverflow.com/a/3471853/313768; przytoczyć tam rozwiązanie:
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..."