Multithreading - mehrere Threadobjekte mit ähnlichem Name

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
cruzer*
User
Beiträge: 21
Registriert: Mittwoch 4. September 2013, 10:50

Hallo,
ich habe ein Thread und möchte diesen unter mehreren gleich aufgebauten Namen öfters starten.
ca so:

Code: Alles auswählen

class meinThread(threading.Thread):
   ...

thread1 = meinThread(arg)
thread2 = meinThread(arg)
thread3 = meinThread(arg)
thread4 = meinThread(arg)
thread5 = meinThread(arg)
thread6 = meinThread(arg)

thread1.start()
thread2.start()
...
nur möchte ich umgehen, dass ich jeden Thread selber benennen muss. Da ich vorher nicht weiß wieviele ich benötige.
ich habe nur folgendes gefunden:

Code: Alles auswählen

jobs = []
num = 1
for num in numlist:
    jobs.append(threading.Thread(target=meinThread, name='Thread{0}'.format(num), args = (arg,)))
    num +=1

for j in jobs:
    j.start()
Bei diesem Beispiel wird aus meinThread ein Thread gemacht. Meine Klasse ist aber schon als Thread definiert...
BlackJack

@cruzer*: Und das Problem ist jetzt welches? Dann erzeugst Du halt eine Liste mit Exemplaren von Deiner `Thread`-Unterklasse.

Wobei das Beispiel da unsinnig ist, denn `num` wird aus `numlist` bezogen was nirgends definiert ist. Falls es definiert ist, macht das initialisieren vor der Schleife und das addieren von 1 am Ende der Schleife keinen Sinn, weil beide Operationen im Grunde keinen sinvollen Effekt haben.

`name` bei den Threads zu setzen macht auch nicht viel Sinn wenn Du das nicht später auch für irgend etwas verwendest.
cruzer*
User
Beiträge: 21
Registriert: Mittwoch 4. September 2013, 10:50

Ja das Beispiel war ein bisschen doof.

Code: Alles auswählen

jobs = []
alist = ['a','b','c','d']
num = 1
for x in alist:
    jobs.append(threading.Thread(target=meinThread, name='Thread{0}'.format(num), args = (x,num,)))
    num +=1
 
for j in jobs:
    j.start()
 
So ergibt es Sinn.

Ich muss später auf eine Liste innerhalb der einzelnen Thread zugreifen. Und deshalb muss ich vorher wissen wie sie heissen.
BlackJack

@cruzer*: Das verstehe ich nicht, willst Du dann etwa immer die Liste linear durchsuchen? Ich denke Du hast das `name` falsch verstanden. Das ist einfach nur ein Wert den man mit der `getName()`-Methode wieder abfragen kann. Dazu muss man das Objekt selbst aber schon haben, denn sonst könnte man die Methode darauf ja nicht aufrufen. Dieser Name kann bei der Fehlersuche ganz praktisch sein, aber ansonsten ist der eher nicht sinnvoll.
cruzer*
User
Beiträge: 21
Registriert: Mittwoch 4. September 2013, 10:50

Ich glaube, es geht auch nicht so, wie ich es mir vorgestellt habe...

ThreadX() hat eine Liste. Anhand einer ID erkenne ich, dass das Objekt zu ThreadX gehört. In diesem Thread soll dann die Liste um ein Objekt erweitert werden.

Den Namen finde ich mit globals()['Thread{0}'.format(data.num)]
BlackJack

@cruzer*: Um himmels willen, generierte Namen auf die dann gar nicht mehr per Namen im Quelltext zugegriffen wird sondern immer über so etwas komisches umständliches machen überhaupt keinen Sinn. Dafür gibt es Wörterbücher (`dict`). Und durchnummerierte Namen machen auch keinen Sinn. Das will man eigentlich eine Liste haben. Die Elemente dort haben ja eine Nummer, nämlich den Index. Dazu müsstest Du einfach nur mit 0 mit der Nummerierung anfangen. Solche Datenstrukturen global zu verwalten ist auch keine so tolle Idee.
cruzer*
User
Beiträge: 21
Registriert: Mittwoch 4. September 2013, 10:50

Du hast recht, wenn ich die Threads eh in einer Liste jobs[] zusammen fasse, brauche ich den namen nicht.
Bei der ID fange ich mit 1 an und erhöhe um 100 so komme ich mit id/100 immer auf die richtige id und Listenindex. (id wird erhöht deshalb der Spielraum)

Wie starte ich denn mehrere Threads ohne sie zu benennen?
Die Threads bekommen jeweils andere Argumente, die in einer Liste gespeichert sind, die aus einer txt eingelesen wird.
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

@cruzer*:
Mit Verlaub, ich bin mir nicht sicher, ob Du mit Threadprogrammierung derzeit glücklich wirst, da Du hier sehr elementare Dinge fragst und Threads sehr garstig sein können.

Evtl. ist Dir besser geholfen, wenn Du uns mal Dein eigentliches Problem schilderst. Der Versuch, viele Threads mit unterschiedlichen Parametern zu starten, klingt wie der falsche Lösungsansatz. Wahrscheinlich ist Dir mit einer Queue besser geholfen.
cruzer*
User
Beiträge: 21
Registriert: Mittwoch 4. September 2013, 10:50

@ jerch:
Mir fehlte grundlegendes Wissen über Threads. Dennoch bin ich damit jetzt einigermaßen "glücklich" geworden:

gelöst habe ich es so:

Code: Alles auswählen

    idnt = 1  
    for ip in ip_list:
        jobs.append(thread(arg,idnt))
        idnt += 1
    try:
        for job in jobs:
            job.start()
mit job kann ich nun auch die laufenden Threads ansprechen und muss den namen gar nicht kennen :) Zuordnen kann ich mit idnt. Danke dafür @Blackjack
Benutzeravatar
sparrow
User
Beiträge: 4195
Registriert: Freitag 17. April 2009, 10:28

Du solltest immer ab 0 zählen, dann kannst du auch enumerate verwenden.
Und du kannst, wenn du schon dabei bist, das ganze in einer Schleife starten.

Code: Alles auswählen

for idnt, ip in enumerate(ip_list):
    new_thread = thread(arg,idnt)
    new_thread.start()
    jobs.append(new_thread)
BlackJack

@cruzer*: Wobei ich es ein wenig eigenartig finde das `ip` überhaupt nicht verwendet wird.

Ausserdem sollte man weder versuchen Konsonanten zu sparen, die sind nämlich nicht teurer als andere Buchstaben, noch konkrete Typen in den Namen schreiben.

`thread` ist eine Klasse und sollte dementsprechend nicht mit einem Kleinbuchstaben beginnen, ausserdem ist es ein Thread-Typ mit einer spezifischeren Bedeutung als der allgemeine `threading.Thread`, was sich auch im Namen widerspiegeln sollte. Ich nenne den Typ mal `SomeThread` weil ich nicht weiss was die Bedeutung ist.

Der `new_*`-Präfix scheint hier keinen Sinn zu machen wenn es nicht auch so etwas wie einen `old_thread` gibt. Falls das da nur steht, weil der Name `thread` schon für den Typ vergeben war: Genau das ist einer der Gründe warum es die Namenskonvention für Klassen gibt — das man „automatisch” einen generischen Namen für ein Exemplar hat ohne sinnfreie Präfixe wie `my_` oder `new_` erfinden zu müssen.

Code: Alles auswählen

    jobs = list()
    for identifier in xrange(len(ips)):
        thread = SomeThread(argument, identifier)
        thread.start()
        jobs.append(thread)
Antworten