Multithreading - Problem

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.
blubber
User
Beiträge: 123
Registriert: Montag 19. März 2007, 09:08

Multithreading - Problem

Beitragvon blubber » Dienstag 21. August 2007, 08:19

Hi,

hab ein Problem mit meinem Multithreading - System. Und zwar hab ich über eine GUI die Möglichkeit, verschiedene Testbereiche (Register) auszuwählen. Jedes Register enthält Anzahl n Testfälle. Außerdem stellt jedes Register einen eigenen Thread dar. Wenn man nun alle Testfälle in allen Registern selektiert, dann laufen logischerweise alle Threads gleichzeitig an, was bedeutet, dass auch jeder erste Test eines jeden Registers zur selben Zeit anläuft. Die ist doof, weil zur selben Zeit immer nur ein Test laufen darf. Gibt es da eine Möglichkeit, dass sich die Threads gegenseitig "pausieren", also dass immer nur 1 Thread zur selben Zeit läuft? Über ein Token evtl?

Gruß
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Beitragvon rayo » Dienstag 21. August 2007, 09:59

Hi


Warum multithreaded wenns sowieso nur seriell ablaufen soll?

Mach nur einen zusätzlichen Thread (nicht pro Tab einen) der eine Queue (Modul Queue) abarbeitet, in diese Queue kannst du alle Testfälle hinzufügen.

Gruss
blubber
User
Beiträge: 123
Registriert: Montag 19. März 2007, 09:08

Beitragvon blubber » Dienstag 21. August 2007, 10:30

hallo rayo,

erstmal Danke für Deinen Vorschlag. Es ist halt momentan Multithreaded, weil jeder Tab dynamisch als eigene Klasse aufgebaut wird, da die Anzahl der Tabs variieren kann. Und da ein Thread in Python ja quasi eine Klasse darstellt, habe ich Anzahl Tabs = Anzahl Threads. Das funktioniert an sich auch super, so lange man immer erst Testfälle in einem Tab abarbeiten lässt und dann Testfälle in einem anderen Tab startet, also nacheinander.

Aber ich lass mir Deinen Vorschlag mal durch den Kopf gehen. Ich müsste quasi eine neue, feste Klasse anlegen, welche den Thread darstellt, und dieser Thread wird dann immer gestartet und arbeitet die Testfälle in einer Queue ab, oder? So meintest Du das?
lunar

Beitragvon lunar » Dienstag 21. August 2007, 10:40

blubber hat geschrieben:hallo rayo,

erstmal Danke für Deinen Vorschlag. Es ist halt momentan Multithreaded, weil jeder Tab dynamisch als eigene Klasse aufgebaut wird, da die Anzahl der Tabs variieren kann. Und da ein Thread in Python ja quasi eine Klasse darstellt, habe ich Anzahl Tabs = Anzahl Threads. Das funktioniert an sich auch super, so lange man immer erst Testfälle in einem Tab abarbeiten lässt und dann Testfälle in einem anderen Tab startet, also nacheinander.

Dafür brauchst du keine Threads... du könntest auch einfach seriell über alle Tabs iterieren (das wäre wahrscheinlich nicht nur einfacher zu programmieren, sondern auch schneller in der Ausführung). Mir scheint, du hast den Sinn von Threads nicht ganz verstanden...
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Beitragvon rayo » Dienstag 21. August 2007, 10:43

Hi

Also ich würde 1 Thread der immer "läuft" erstellen, er wartet einfach bis du x Testfälle hinzufügst und arbeitet diese immer ab.

Hier mal ein kleines Beispiel.


Code: Alles auswählen

from threading import Thread
from Queue import Queue

from time import sleep
from random import random

class Worker(Thread):
    def __init__(self):
        Thread.__init__(self)
        self.test_cases = Queue()

    def run(self):
        while 1:
            test_case, callback = self.test_cases.get()

            print 'arbeit %s ab' % test_case
            sleep(random()*2)
            print '%s abgeschlossen' % test_case
            callback(test_case)

    def add_test_case(self, test_case, callback):
        self.test_cases.put((test_case,callback))

w = Worker()
w.start()

def callback(testfall):
    print '%s wurde vom worker_thread abgearbeitet' % testfall

for y in range(5): #tabs
    for x in range(5): #test_cases
        w.add_test_case("test_%d_%d" % (y, x), callback)

raw_input('alle Testfälle hinzugefügt')


Der Thread macht einfach nichts solange er keine Testfälle in der Queue hat (queue.get blockiert bis was drin ist).

Gruss
blubber
User
Beiträge: 123
Registriert: Montag 19. März 2007, 09:08

Beitragvon blubber » Dienstag 21. August 2007, 11:13

Ja ok, werde ich mal ausprobieren, vielen Dank.

@lunar: Doch, ich benötige schon Threads. Schon alleine aus dem Grund, weil es sonst zu Problemen mit der grafischen Aufbereitung kommt, wenn man GUI und Rest nicht voneinander trennt.
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Dienstag 21. August 2007, 13:53

blubber hat geschrieben:@lunar: Doch, ich benötige schon Threads. Schon alleine aus dem Grund, weil es sonst zu Problemen mit der grafischen Aufbereitung kommt, wenn man GUI und Rest nicht voneinander trennt.

Ja, 2 Threads: GUI-Thread und Worker-Thread.

Wobei, unter PyGTK kannst du das alles auch in einem Thread erledigen, da gibt es extra Pseudothreads dafür.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Beitragvon veers » Dienstag 21. August 2007, 15:13

Leonidas hat geschrieben:Wobei, unter PyGTK kannst du das alles auch in einem Thread erledigen, da gibt es extra Pseudothreads dafür.
Pseudo Threads?
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Mittwoch 22. August 2007, 08:27

veers hat geschrieben:Pseudo Threads?

Da sich GTK nicht gut mit Threads versteht und es recht kompliziert ist, sie zu nutzen gibt es ``gobject.timeout_add()`` und ``gobject.idle_add()`` die Code asynchron ausführen, damit die anzeige der GUI nicht blockiert.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Beitragvon veers » Mittwoch 22. August 2007, 09:40

Leonidas hat geschrieben:
veers hat geschrieben:Pseudo Threads?

Da sich GTK nicht gut mit Threads versteht und es recht kompliziert ist, sie zu nutzen gibt es ``gobject.timeout_add()`` und ``gobject.idle_add()`` die Code asynchron ausführen, damit die anzeige der GUI nicht blockiert.
Achso ja, aber das sind ja nicht wirklich Pseudothreads. Lässt sich jedoch mit Iteratoren und etwas Leim zusammen fast wie Koroutinen verwenden. :)
blubber
User
Beiträge: 123
Registriert: Montag 19. März 2007, 09:08

Beitragvon blubber » Donnerstag 23. August 2007, 09:00

OK, falls es jemanden interessiert, ich habe es nun so gelöst:

Ein weiterer Thread (Start-Thread) ruft in einer Schleife einfach die einzelnen Tab - Threads nacheinander auf, was über Events gesteuert wird. Also quasi Start - Thread startet ersten Tab - Thread und macht dann ein event.wait(), und der erste Tab - Thread setzt am Schluss das Event, so dass in der Schleife der zweite Tab - Thread aufgerufen wird usw usw.
Das funktioniert ganz gut und war mit geringfügiger Umstrukturierung von meinem bisherigen Code möglich.

Danke für die Hilfe
Gruß

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder