Seite 1 von 1

Nur einen Thread starten ?

Verfasst: Dienstag 2. November 2021, 20:26
von PythonCodingFun
Hallo Community,

ich habe eine Threading-Frage, ich kann in meinem Programm einen weiteren Thread starten, aber wie schaffe ich es das ich nur einen weiteren Thread starten kann, nicht 2 nicht 3 ...

Ich denke das mein Problem ist das ich bei jedem Aufruf von startThread() einen neuen Thread starte, aber wie schaffe ich es das ich nur einen Thread starte wenn bisher noch keiner erstellt wurde, und falls es einen gibt soll die Anfrage verworfen werden.

hier mal ein kleienr Auszug:

Klasse Utils:

Code: Alles auswählen

class Utils(threading.Thread):
           def __init__(self, *args, **kwargs):
                 super(Utils, self).__init__(*args, **kwargs)
                 self.event = threading.Event()

           def nicefunc(self):
           #....
Startklasse:

Code: Alles auswählen

 def startthread(self):
        self.utils = Utils(target=self.loop)
        self.utils.start()

        print("Anzahl Threads nach den Start: ",threading.active_count())


 def loop(self):
        while not self.isstopped():
               self.utils.nicefunc()
            
#....            
  

Re: Nur einen Thread starten ?

Verfasst: Dienstag 2. November 2021, 20:37
von Sirius3
Methoden werden komplett klein geschrieben. Deine Attribute haben ein bis zwei führende Unterstriche zu viel. Die Einrückungen sind falsch und es fehlen Doppelpunkte.

Das Problem ist sehr unkonkret beschrieben. Die einfachste Lösung ist es, nur einen Thread zu starten. Wie und wann Threads gestartet werden, hat man ja als Programmiererin in der Hand.

Für eine genauere Antwort mußt Du Dein Problem genauer beschreiben.

Re: Nur einen Thread starten ?

Verfasst: Dienstag 2. November 2021, 20:46
von PythonCodingFun
Sirius3 hat geschrieben: Dienstag 2. November 2021, 20:37
Das Problem ist sehr unkonkret beschrieben. Die einfachste Lösung ist es, nur einen Thread zu starten. Wie und wann Threads gestartet werden, hat man ja als Programmiererin in der Hand.

Für eine genauere Antwort mußt Du Dein Problem genauer beschreiben.
Hii,
bisher ist es möglich das der Nutzer beliebig viele Threads starten kann, ich suche einen Ansatz mit dem es möglich ist, das der Nutzer nur einen Thread starten kann, egal wie oft startthread() aufgerufen wird.

Re: Nur einen Thread starten ?

Verfasst: Dienstag 2. November 2021, 21:29
von __deets__
Dann starte doch nur einen Thread. Und schmeiß die start Thread Methode weg.

Re: Nur einen Thread starten ?

Verfasst: Donnerstag 4. November 2021, 12:21
von PythonCodingFun
__deets__ hat geschrieben: Dienstag 2. November 2021, 21:29 Dann starte doch nur einen Thread. Und schmeiß die start Thread Methode weg.
Ich glaube ich werde ein wenig falsch verstanden. :D
Ich möchte das mein Programm neben seinem eigenen Thread nur einen weiteren Thread (aus Utils) startet kann und wie kann ich es verhindern das weitere Threads aus Utils gestartet werden können.

Re: Nur einen Thread starten ?

Verfasst: Donnerstag 4. November 2021, 12:31
von __blackjack__
@PythonCodingFun: Ich denke wir haben schon verstanden. Starte halt nur einen. Nein, das verhindert nicht das noch einer gestartet wird, aber das muss man ja auch nicht, wenn man nur einen startet. Das ist wie bei Singletons: Man kann da irgendwelche Metamagie machen um zu verhindern das mehr als ein Objekt erstellt wird, man kann aber auch ganz einfach nur ein Objekt erstellen und gut ist.

`self.utils` ist ja in der `__init__()` mal mit `None` belegt worden. Ist es doch, oder etwa nicht? Da kann man testen ob das noch `None` ist oder schon nicht mehr.

Re: Nur einen Thread starten ?

Verfasst: Donnerstag 4. November 2021, 12:54
von PythonCodingFun
__blackjack__ hat geschrieben: Donnerstag 4. November 2021, 12:31 @PythonCodingFun: Ich denke wir haben schon verstanden. Starte halt nur einen. Nein, das verhindert nicht das noch einer gestartet wird, aber das muss man ja auch nicht, wenn man nur einen startet. Das ist wie bei Singletons: Man kann da irgendwelche Metamagie machen um zu verhindern das mehr als ein Objekt erstellt wird, man kann aber auch ganz einfach nur ein Objekt erstellen und gut ist.

`self.utils` ist ja in der `__init__()` mal mit `None` belegt worden. Ist es doch, oder etwa nicht? Da kann man testen ob das noch `None` ist oder schon nicht mehr.
Hallo, ich weiß eines meiner Probleme ist, ich verständige mich sehr umständlich, sorry ;)

Aber zum Thema ich habe spaßes halber einen Singleton "gebastelt" ,der nur eine Instanz der Utils Klasse anlegt ich kann es zumindest kanalisieren ,das nur ein Thread gestartet wird, aber wenn ich den Thread "beende" also mit Event und is_set() und set() .... kann ich danach keinen keinen neuen Thread starten, denn dann erhalte ich die Expection threads can only be started once

Re: Nur einen Thread starten ?

Verfasst: Donnerstag 4. November 2021, 12:56
von __deets__
Na dann beende den doch nicht. Warum darf der nicht beim Start des Programms auch starten, und die ganze Zeit “leben”? Und bekommt zb via Queue Arbeitsaufträge.

Re: Nur einen Thread starten ?

Verfasst: Donnerstag 4. November 2021, 13:03
von PythonCodingFun
__deets__ hat geschrieben: Donnerstag 4. November 2021, 12:56 Na dann beende den doch nicht.
Beenden klappt ja im sinne von das ich aus einer while schleife (is_set() ...) rauskomme und somit der thread seine Arbeit "niederlegt" nach der letzten Iteration. mir geht es nur um die Anzahl der Threads^^

Re: Nur einen Thread starten ?

Verfasst: Donnerstag 4. November 2021, 13:07
von __deets__
Aber dann lass das doch. Beende ihn einfach nicht. Ein neuer thread ist doch nicht irgendwie besser oder sowas. Der alte ist doch noch gut(tm). Kann es sein, dass du hier eigentlich ein ganz anders Problem lösen willst? Nämlich das ein User keine weitere Aktion auslösen kann, während die alte noch läuft? Das hat nichts mit Threads zu tun, sondern dann muss eben der Button disabled werden oder so. Und trotzdem reicht ein thread, statt andauern ein neuer.

Re: Nur einen Thread starten ?

Verfasst: Donnerstag 4. November 2021, 13:21
von PythonCodingFun
__deets__ hat geschrieben: Donnerstag 4. November 2021, 13:07 Aber dann lass das doch. Beende ihn einfach nicht. Ein neuer thread ist doch nicht irgendwie besser oder sowas. Der alte ist doch noch gut(tm). Kann es sein, dass du hier eigentlich ein ganz anders Problem lösen willst? Nämlich das ein User keine weitere Aktion auslösen kann, während die alte noch läuft? Das hat nichts mit Threads zu tun, sondern dann muss eben der Button disabled werden oder so. Und trotzdem reicht ein thread, statt andauern ein neuer.
Ja also ich will halt den User daran hindern zwei threads zu starten, wenn ich z.b den Aufruf disable o.dgl, dann besteht doch davor die Gefahr das, das man durch zwei parallele Aufrufe trotzdem zwei threads starten kann, oder so ?! :?: Oder denke ich (mal wieder) falsch :shock:

Re: Nur einen Thread starten ?

Verfasst: Donnerstag 4. November 2021, 13:23
von __deets__
Wie ruft man denn parallel auf, wenn der erste Aufruf den Button disabled hat? Es gibt nur einen GUI thread. Übrigens aus genau dem Grunde.

Und bitte nicht den gesamten Post davor zitieren. Der steht da schon.

Re: Nur einen Thread starten ?

Verfasst: Donnerstag 4. November 2021, 15:01
von pillmuncher
PythonCodingFun hat geschrieben: Donnerstag 4. November 2021, 13:21 Ja also ich will halt den User daran hindern zwei threads zu starten, wenn ich z.b den Aufruf disable o.dgl, dann besteht doch davor die Gefahr das, das man durch zwei parallele Aufrufe trotzdem zwei threads starten kann, oder so ?! :?: Oder denke ich (mal wieder) falsch :shock:
Du könntest auch einfach gleich am Anfang den zweiten Thread starten, der zunächst auf Input aus einer Queue wartet. Sobald der Benutzer auf den Button drückt, wird der Button disabled und die Daten werden über die Queue an den zweiten Thread übermittelt. Wenn der besagter Thread fertig ist mit der Arbeit, aktiviert den Button wieder wieder und geht zurück in den Wartemodus.

Ungefähr nach diesem Schema:

Code: Alles auswählen

import tkinter as tk

from threading import Thread
from queue import Queue

KILL_ME_ALREADY = object()

class SomeWindow(tk.Tk):

    def __init__(self):
        def do_stuff():
            while True:
                data = self.queue.get()
                if data is KILL_ME_ALREADY:
                    return
                else:
                    # do the stuff here:
                    ...
                    self.button_enabled = True
        self.queue = Queue()
        self.button = tk.Button(self, text='Click Me!!', command=self.on_button_click)
        self.button_enabled = True
        self.second_thread = Thread(target=do_stuff)
        self.second_thread.start()
        ...

    def on_quit(self):
        self.queue.put(KILL_ME_ALREADY)

    def enable_button_when_ready(self):
        if self.button_enabled = True
            self.button['state'] = tk.NORMAL
        else:
            self.after(100, self.enable_button_when_ready)

    def on_button_click(self):
        self.button['state'] = tk.DISABLED
        self.button_enabled = False
        some_data = ...
        self.queue.put(some_data)
        self.enable_button_when_ready()
Disclaimer: Ich hab seit Jahren nichts mehr mit tkinter zu tun gehabt.