Zeitgesteuerte Python-Eingabe

Oct 14 2020

Ich schreibe einen Python-Game-Bot, bei dem ein Benutzer innerhalb einer bestimmten Zeit eine Eingabe senden muss.

Meine aktuelle Implementierung besteht darin, einen neuen Thread zu erzeugen, der für diese Zeitspanne inaktiv ist, und dann zu überprüfen, ob eine Eingabe gesendet wurde. Ein Nonce wird hinzugefügt, da die Zeit nach dem Start eines anderen Threads ablaufen kann, wodurch das if chatid in user_threadsTeil als wahr ausgewertet wird. Sollte ich diese Methode verwenden oder gibt es eine bessere Lösung für eine zeitgesteuerte Eingabe (in dem Sinne, dass es weniger wahrscheinlich ist, dass sie aufgrund ähnlicher Rennbedingungen fehlschlägt).

Ich habe auch versucht multiprocessing.Process, Variablen für den anderen Prozess zu verwenden, aber es scheint viel umständlicher zu sein.

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

Antworten

2 Reinderien Oct 14 2020 at 00:41

Was @vnp gesagt hat. Grundsätzlich ist

  • inputverwendet stdin;
  • stdin kann als Dateihandle interpretiert werden, solange Sie nicht in Windows sind;
  • select kann auf Datenverfügbarkeit auf solchen Handles warten.

Es gibt eine Menge Internet-Hilfe zu diesem Thema, einschließlich https://stackoverflow.com/a/3471853/313768;; um dort die Lösung zu zitieren:

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