Entrée chronométrée Python

Oct 14 2020

J'écris un game-bot python où un utilisateur doit envoyer une entrée dans un certain laps de temps.

Ma mise en œuvre actuelle de ceci est de générer un nouveau thread qui dort pendant ce laps de temps, puis vérifie si une entrée a été envoyée. Un nonce est ajouté car le temps pourrait s'écouler après le démarrage d'un autre thread, ce qui entraînerait l' if chatid in user_threadsévaluation de la pièce à true. Dois-je utiliser cette méthode ou y a-t-il une meilleure solution pour avoir une entrée chronométrée (dans le sens moins susceptible d'échouer en raison de conditions de course similaires).

J'ai également essayé d'utiliser multiprocessing.Processmais partager des variables avec l'autre processus semble être beaucoup plus fastidieux.

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")

Réponses

2 Reinderien Oct 14 2020 at 00:41

Ce que @vnp a dit. Fondamentalement,

  • inpututilisations stdin;
  • stdin peut être interprété comme un descripteur de fichier tant que vous n'êtes pas sous Windows;
  • select peut attendre la disponibilité des données sur ces poignées.

Il y a beaucoup d'aide Internet sur ce sujet, y compris https://stackoverflow.com/a/3471853/313768; pour y citer la solution:

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..."