Hallo.
Ich bin mir nicht ganz sicher wohin das Thema genau gehört. Hoffe mir kann jemand helfen.
Mein Problem bzw. Ausgangssituation:
Ich habe ein Script für den Streamlabs Chatbot geschrieben, dass den Chat überwacht und auf verschiedene Dinge reagiert.
Nun wollte ich den Bot um eine weitere Funktion erweitern, ende aber jedesmal in einer Endlosschleife.
Wenn im Chat für eine bestimmte Zeit keine Nachrichten mehr erscheinen, soll der Bot selbst etwas schreiben. Jedes Mal wenn eine Nachricht kommt, soll der Timer jedoch zurückgesetzt werden. Ich habe es soweit hinbekommen, dass jede Nachricht den Bot aushebelt, aber wenn die Zeit um ist, kommen für jede Nachricht im Chat eine Nachricht vom Bot. (Es sollte aber nur eine kommen.) Im Moment benutze ich threading.thread dafür. Dies scheint aber nicht die richtige Wahl zu sein, da man diese nicht "abbrechen" kann (Google).
Hat jemand eine Idee, wie ich ein "Hintergrundprogramm" laufen lasse, dass den Bot wie bei Thread nicht anhält, aber bei jeder Nachricht gestoppt und neu gestartet werden kann?
Ich hoffe man kann ungefähr verstehen was mein Ziel ist.
Außerdem: Ich möchte keine fertigen Scripts, da ich es sonst nicht lerne. Nur Ideen bzw. Schlagworte, mit denen ich das Ziel erreichen könnte.
Gruß Nemi
Threads oder Unterprogramme?
- __blackjack__
- User
- Beiträge: 13100
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Nemi: Das sind zu wenige Informationen um wirklich etwas sagen zu können.
Es stimmt das man einen Thread nicht hart von ausserhalb des Threads abbrechen kann, aber man kann den Thread ja entweder von selbst beenden, oder ihn darüber informieren, das er sich selbst beenden soll. Auch bei Prozessen wäre es ein komischer Entwurf wenn man die einfach hart beendet, ohne mit ihnen zu kooperieren. Zumindest in diesem geschilderten Fall.
Es stimmt das man einen Thread nicht hart von ausserhalb des Threads abbrechen kann, aber man kann den Thread ja entweder von selbst beenden, oder ihn darüber informieren, das er sich selbst beenden soll. Auch bei Prozessen wäre es ein komischer Entwurf wenn man die einfach hart beendet, ohne mit ihnen zu kooperieren. Zumindest in diesem geschilderten Fall.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
@__blackjack__
Danke für die schnelle Reaktion.
Wie genau würde ich das machen mit dem Selbstabbruch des Threads? Eine globale Variable?
Im Moment macht mein Script folgendes:
1. Chat bekommt Nachricht.
2. Bot merkt sich die Zeit in einer Variable und startet Thread.
3. Thread beobachtet die Varibale und reagiert nach der eingestellten Zeit.
Falls nun aber eine Nachricht kommt bevor die zeit abgelaufen ist, wird die Variable ja überschrieben. D.h. Thread reagiert nicht. ABER sobald Thread reagiert, kommen alle Threads hintereinander, da ja bei jeder Nachricht ein Thread gestartet wurde.
Ich bräuchte also eine "Funktion" die den aktuellen Thread schließt, wenn die Zeitvariable überschrieben wurde.
Danke für die schnelle Reaktion.
Wie genau würde ich das machen mit dem Selbstabbruch des Threads? Eine globale Variable?
Im Moment macht mein Script folgendes:
1. Chat bekommt Nachricht.
2. Bot merkt sich die Zeit in einer Variable und startet Thread.
3. Thread beobachtet die Varibale und reagiert nach der eingestellten Zeit.
Falls nun aber eine Nachricht kommt bevor die zeit abgelaufen ist, wird die Variable ja überschrieben. D.h. Thread reagiert nicht. ABER sobald Thread reagiert, kommen alle Threads hintereinander, da ja bei jeder Nachricht ein Thread gestartet wurde.
Ich bräuchte also eine "Funktion" die den aktuellen Thread schließt, wenn die Zeitvariable überschrieben wurde.
- __blackjack__
- User
- Beiträge: 13100
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Nemi: Bloss keine globale Variable. Die sind ja so schon die Pest aber bei nebenläufiger Programmierung sind sie eine noch viel schlechtere Idee als sonst schon.
Es gibt im `threading`-Modul Datentypen um threadsicher auf Daten zuzugreifen. Zudem sind auch die Queue-Objekte aus dem `queue`-Modul threadsicher.
Bei Deinem jetzigen Vorgehen kann der Thread ja bevor er etwas macht, prüfen ob er denn überhaupt noch etwas machen muss. Andererseits macht es auch nicht so viel Sinn bei jeder Nachricht einen neuen Thread zu starten. Sinnvoll wäre es *einen* Thread zu starten, der immer mal wieder aufwacht und schaut ob er etwas machen muss. Den kann man über neu ankommende Nachrichten über eine Queue informieren, und wenn er eine gewisse Zeit keine neue Nachricht bekommt, kann er auf die letzte die angekommen ist, irgendwie reagieren.
Es gibt im `threading`-Modul Datentypen um threadsicher auf Daten zuzugreifen. Zudem sind auch die Queue-Objekte aus dem `queue`-Modul threadsicher.
Bei Deinem jetzigen Vorgehen kann der Thread ja bevor er etwas macht, prüfen ob er denn überhaupt noch etwas machen muss. Andererseits macht es auch nicht so viel Sinn bei jeder Nachricht einen neuen Thread zu starten. Sinnvoll wäre es *einen* Thread zu starten, der immer mal wieder aufwacht und schaut ob er etwas machen muss. Den kann man über neu ankommende Nachrichten über eine Queue informieren, und wenn er eine gewisse Zeit keine neue Nachricht bekommt, kann er auf die letzte die angekommen ist, irgendwie reagieren.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
@__blacjack__:
genau sowas suche ich xD
Habe auch grad versucht etwas in der Art einzupflegen.
1. Beim Starten des Bots wird die Funktion Background gestartet, die den Thread startet. Variable für Zeitfenster wird auch gesetzt.
2. Thread arbeitet mit while-Schleife, die die Zeit im Auge behält. Sobald die Zeit überschritten ist, verlässt der Thread die Schleife und startet Funktion Text sowie Background.
3. Funktion Text schreibt gewünschten Text.
ABER nun wieder Endlosschleife... ständig kommt der Text erneut, auch wenn ich (durch Chat-Nachricht) die Variable ändere.
Was genau mache ich falsch?
@__deets__:
Wie würde es mit Timer aussehen? Mein Problem ist halt, dass alle anderen Funktionen nebenbei weiterlaufen müssen.
Ja es gibt eine große Anleitung für den Bot aber wenig für die Python-Einbindung.
genau sowas suche ich xD
Habe auch grad versucht etwas in der Art einzupflegen.
1. Beim Starten des Bots wird die Funktion Background gestartet, die den Thread startet. Variable für Zeitfenster wird auch gesetzt.
2. Thread arbeitet mit while-Schleife, die die Zeit im Auge behält. Sobald die Zeit überschritten ist, verlässt der Thread die Schleife und startet Funktion Text sowie Background.
3. Funktion Text schreibt gewünschten Text.
ABER nun wieder Endlosschleife... ständig kommt der Text erneut, auch wenn ich (durch Chat-Nachricht) die Variable ändere.
Was genau mache ich falsch?
@__deets__:
Wie würde es mit Timer aussehen? Mein Problem ist halt, dass alle anderen Funktionen nebenbei weiterlaufen müssen.
Ja es gibt eine große Anleitung für den Bot aber wenig für die Python-Einbindung.
Timer erlauben genau das. Statt einer Nachricht von einem Benutzer bekommst du eine Nachricht „timer fertig“.
Und der Vorteil des Timers ist: alles was du darin tust kannst du dann einfach als Nachricht verschicken etc.
wohingegen der Thread explizit mit der ereignisschleife verheiratet werden muss. Du kannst NICHT einfach aus dem Thread Nachrichten verschicken. Zumindest nicht, solange das explizit erwähnt & dokumentiert wurde. Darum die Frage danach, welche Python API du benutzt.
Und der Vorteil des Timers ist: alles was du darin tust kannst du dann einfach als Nachricht verschicken etc.
wohingegen der Thread explizit mit der ereignisschleife verheiratet werden muss. Du kannst NICHT einfach aus dem Thread Nachrichten verschicken. Zumindest nicht, solange das explizit erwähnt & dokumentiert wurde. Darum die Frage danach, welche Python API du benutzt.
@__deets__:
Da bin ich jetzt völlig raus. Keine Ahnung welche API ich benutze Q_Q Habe mich aber zum Timer grad mal belesen:
So steht es jetzt im Script. Aber anstatt der 10 Sekunden kommt der Text sofort?!
Das cancel soll den (eventuell schon bestehenden) Timer stoppen.
Da bin ich jetzt völlig raus. Keine Ahnung welche API ich benutze Q_Q Habe mich aber zum Timer grad mal belesen:
Code: Alles auswählen
t = threading.Timer(10.0, TalkingBot(random.randint(1, 10)))
t.cancel()
t.start()
Das cancel soll den (eventuell schon bestehenden) Timer stoppen.
Na du redest doch mit dem Chat-System. Das ist eine API. Was fuer Kommandos setzt du da ab, wie wirst du von User-Nachrichten in Kenntnis gesetzt. Etc.
Und das ist nicht der Timer, den ich meinte. Das ist immer noch ein Thread, und hat die Probleme die ich ansprach.
Und das ist nicht der Timer, den ich meinte. Das ist immer noch ein Thread, und hat die Probleme die ich ansprach.
achso, die api steckt schon in dem streamlabs chatbot drin, ich bekomme quasi fertige daten wie zum beispiel "data.isfromtwitch" oder "data.isfromchat" usw.
welchen timer meinst du dann? in der Hilfe von python ist nur dieser
welchen timer meinst du dann? in der Hilfe von python ist nur dieser
Ja. In Python ist nur der. Aber es geht um deinen Chatbot. In ganz Python steht nix von streamlabs. Das ist also irgendwie integriert. Als Paket, eingebetteter Interpreter oder was auch immer. Und DIESE INTEGRATION sollte so ein Feature haben.
Also ich habe mal kurz gegoogelt & das hier gefunden:
https://github.com/Bare7a/Streamlabs-Ch ... sSystem.py
Und so wie das aussieht gibt es da eine Tick-Methode, die regelmaessig aufgerufen wird. Und in der man solche Probleme wie deines loest.
https://github.com/Bare7a/Streamlabs-Ch ... sSystem.py
Und so wie das aussieht gibt es da eine Tick-Methode, die regelmaessig aufgerufen wird. Und in der man solche Probleme wie deines loest.
die tick-methode hilft mir glaube ich nicht, da es ja das hauptscript unterbricht.
ich bekomm es einfach nicht hin.
Rein logisch passt ja alles:
Solange Nachrichten kommen wird immer wieder der Timer zurückgesetzt. Läuft der Timer ab, kommt der Text.
Aber das Script macht es nicht. Das hat auch nicht wirklich etwas mit der api zu tun. Da ich ja gerade nur versuche einen Timer (thread) zu starten und zu unterbrechen.
ich bekomm es einfach nicht hin.
Rein logisch passt ja alles:
Solange Nachrichten kommen wird immer wieder der Timer zurückgesetzt. Läuft der Timer ab, kommt der Text.
Aber das Script macht es nicht. Das hat auch nicht wirklich etwas mit der api zu tun. Da ich ja gerade nur versuche einen Timer (thread) zu starten und zu unterbrechen.
Natuerlich hilft dir die Tick-Funktion. Jedes mal, wenn der Tick kommt, pruefst du, ob die Zeit verflossen ist. Wenn ja, dann tust du, was du tun willst. In der Execute-Funktion kannst du den Timer nach Bedarf wieder zurueck bzw weiter setzen. Und da wird auch nix unterbrochen. Die laufen unabhaengig voneinander. Execute wenn ein Ereignis reinkommt, und Tick, wenn ein Tick passiert (welche Einheit auch immer der hat).
Du DARFST aus deinem Thread ueberhaupt nichts machen. Wenn du aus dem Thread einfach Parent benutzt, da kann es sehr gut sein, dass der Bot abstuerzt.
Du DARFST aus deinem Thread ueberhaupt nichts machen. Wenn du aus dem Thread einfach Parent benutzt, da kann es sehr gut sein, dass der Bot abstuerzt.
Mal ein kleines Konzept (natuerlich nicht getestet, ich habe dieses Ding ja nicht):
Code: Alles auswählen
CHATTERBOX_TIMEOUT = 10 # nach 10 Sekunden Stille loslabern
chatterbox_timestamp = None
def Execute(data):
global chatterbox_timestamp
chatterbox_timestamp = time.time() + CHATTERBOX_TIMEOUT
def Tick():
global chatterbox_timestamp
if chatterbox_timestamp is not None and chatterbox_timestamp <= time.time():
chatterbox_timestamp = None # nicht dauerlabern
Parent.SendStreamMessage("laber was")
ok dann versteh ich python einfach falsch.
Kenne es nur von anderen Sprachen, dass man Funktionen immer aufrufen muss. Habe in dem Beispiel vorhin zb nicht gesehen, dass Tick aufgerufen wird un dachte deshalb es wird nicht benutzt.
Also läuft Tick dauerhaft mit?
Kenne es nur von anderen Sprachen, dass man Funktionen immer aufrufen muss. Habe in dem Beispiel vorhin zb nicht gesehen, dass Tick aufgerufen wird un dachte deshalb es wird nicht benutzt.
Also läuft Tick dauerhaft mit?
- __blackjack__
- User
- Beiträge: 13100
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Nemi: Das hat nichts mit Python zu tun. Auch in Python muss man Funktionen aufrufen. Das scheint halt die API von diesem Chatbotdingens zu sein, dass das ein Modul haben will, und da nachschaut ob es eine Funktion mit dem Namen `Tick()` gibt, und die dann regelmässig aufruft. ”Normal” ist das für Python nicht. Die API ist so nicht wirklich schön.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Ok ich habe jetzt __deets__ Beispiel eingebaut.
Entweder der Bot schreibt gar nichts oder Endlosschleife. (je nach Typ der Variable, int str)
bzw.
Es scheint ja irgendwas zu funktionieren, aber halt nicht so wie es soll xD
Entweder der Bot schreibt gar nichts oder Endlosschleife. (je nach Typ der Variable, int str)
Code: Alles auswählen
# Random thread to use
def Tick():
if int(MsgTimeStamp) is not 0 and int(MsgTimeStamp) <= int(datetime.datetime.now().strftime("%y%m%d%H%M%S")):
TalkingBot(random.randint(1, 10))
return
Code: Alles auswählen
# Random thread to use
def Tick():
if MsgTimeStamp is not None and MsgTimeStamp <= int(datetime.datetime.now().strftime("%y%m%d%H%M%S")):
TalkingBot(random.randint(1, 10))
return
Wenn du das von anderen Sprachen so kennst, warum hat dich das bei Execute nicht auch gewundert? Das wird doch auch nur aufgerufen, wenn es was zu tun gibt, und laeuft nicht in einer Endlosschleife oder wird von dir selbst aufgerufen.