Entrada cronometrada Python
Estou escrevendo um bot de jogo python em que um usuário precisa enviar uma entrada dentro de um determinado período de tempo.
Minha implementação atual disso é gerar um novo encadeamento que dorme por esse período de tempo e, em seguida, verificar se uma entrada foi enviada. Um nonce é adicionado porque o tempo pode acabar após o início de outro encadeamento, o que faria com que a if chatid in user_threadsparte fosse avaliada como verdadeira. Devo usar este método ou há uma solução melhor para ter uma entrada cronometrada (no sentido de menos probabilidade de falhar devido a condições de corrida semelhantes).
Também tentei usar, multiprocessing.Processmas compartilhar variáveis com o outro processo parece ser muito mais complicado.
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")
Respostas
O que @vnp disse. Fundamentalmente,
inputusastdin;stdinpode ser interpretado como um identificador de arquivo, desde que você não esteja no Windows;selectpode esperar pela disponibilidade de dados em tais identificadores.
Há muita ajuda da Internet neste tópico, incluindo https://stackoverflow.com/a/3471853/313768; para citar a solução lá:
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..."