Neuen Thread starten

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
Markus12
User
Beiträge: 195
Registriert: Dienstag 6. März 2007, 19:32
Wohnort: Frankfurt am Main

Dienstag 1. Januar 2008, 02:46

Hi,
ich habe immer wieder Probleme mit dem Starten neuer Threads :roll:
Dabei gehe ich folgendermaßen vor:

Code: Alles auswählen

import thread

thread.start_new_thread(my_function, ())
Immer öfters gibt es dabei aber Abstürze, sich aufhängende Fenster und eine sich aufhängendes PytonShell...

Im Forum habe ich bei manchen Themen nun auch vom Modul 'threading' gelesen, dass dieses benutzt wird.

So nun meine Fragen:
1. Wie viel Rechenarbeit kann man in einer Funktion unterbringen, die in einem neuen Thread ausgeführt werden soll?
2. Was kann man auf keinen Fall in einem Thread verarbeiten/ausüben?
3. Wann sollte ich die Module 'thread' und wann 'threading' benutzen und warum? :)


Danke schon mal im Vorraus!

Grüße Markus :-)
BlackJack

Dienstag 1. Januar 2008, 09:33

1. Beliebig.

2. Da Du von Fenstern schreibst: Ich kenne kein GUI-Toolkit das es mag, wenn man von verschienden Threads aus auf die GUI zugreift. Vielleicht ist das ja schon das Problem.

Ansonsten gibt's halt die üblichen Probleme, die bei nebenläufiger Programmierung auftreten können, wie Verklemmungen weil mehrere Threads zum Beispiel gegenseitig auf Ressourcen warten und damit nie zum Ende kommen, oder "race conditions" durch den nicht-deterministischen Ablauf der Threads.

3. `threading` weil das eine "höhere" API mit mehr Funktionalität hat.
Markus12
User
Beiträge: 195
Registriert: Dienstag 6. März 2007, 19:32
Wohnort: Frankfurt am Main

Dienstag 1. Januar 2008, 20:42

Danke für deine Antwort :)

Ein einfaches Beispiel:
Ich möchte ein komplettes Fenster mit Quadraten voll'grid'en, sprich alle Quadrate sollen mit dem Grid-Manager platziert werden. Alle Quadrate sollen gleich groß sein. Dafür benutze ich einen neuen Thread, da es sich ohne aufhängt. Dabei gibt es aber nach einigen Zeilen einen Error von Python, der das komplette Programm beendet, sobald ich "ok" drücke...

Das ist mir rätselhaft...
Hat dafür jemand eine Lösung?

Script:

Code: Alles auswählen

from Tkinter import*
import time

def fenster_oeffnen():
    fenster=Tk()
    fenster.state('zoomed')
    fenster.overrideredirect(1)
    
    frame=Frame(fenster)
    frame.pack()

    for _row in range(50):
        for _column in range(70):
            l=Label(frame, width=2, bg='white')
            l.grid(row=_row, column=_column)


Heute hat es ausnahmsweise keine Errors gegeben, als ich das Script ausgeführt habe... Komisch :S

Hat es irgendwelche Vorteile das Modul 'threading' zu benutzen? :)

Gruß Markus
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

Dienstag 1. Januar 2008, 21:08

Markus12 hat geschrieben:Dafür benutze ich einen neuen Thread, da es sich ohne aufhängt.
Wieso? Tkinter + Threads ist generell keine gute Idee. Gehts nicht auch ohne Threads, zB mit .after()?
BlackJack

Dienstag 1. Januar 2008, 21:12

@Markus12: Wie gesagt GUIs und Threads vertragen sich in der Regel nicht. GUIs sollten immer nur von dem Thread aus manipuliert werden, in dem die `mainloop()` läuft.

Der Unterstrich vor den Namen `_row` und `_column` ist übrigens etwas ungewöhnlich und auch nicht notwendig.
Markus12
User
Beiträge: 195
Registriert: Dienstag 6. März 2007, 19:32
Wohnort: Frankfurt am Main

Freitag 4. Januar 2008, 16:17

Ich weiß, dass ich nicht die Variablen '_row' und 'column' hätte nennen müssen, fand ich aber besser so, als dass dann da steht row=row, wenn ich das Ding griden will...
Wie ihr ja in meinem Script gesehen habt, versuche ich ein Feld aus Würfeln auszubauen. 'after' kenne ich, das würde mir hier aber nichts bringen, da ich nicht möchte, dass das Feld zeitverzögert aufgebaut wird, sondern überhaupt, dass es aufgebaut wird und man es sehen kann^^. Und da habe ich vom Modul 'thread' gelesen, bei dem gewisse Dinge in einem anderen Prozess erledigt werden.
Und das wollte ich hier anwenden, da es ohne Thread leider nicht geht. Bei der ganzen Gridgeschichte dauert das Aufbauen des Feldes anscheinend so lange, dass Python sich komplett aufhängt! :S

Vor einigen Monaten bin ich beim Testen, warum es sich aufhängt, zufällig auf eine solche Variante meiner Funktion gestoßen; Und das ganze sieht dann so aus:

Code: Alles auswählen

from Tkinter import*
import time

def fenster_oeffnen():
    fenster=Tk()
    fenster.state('zoomed')
    fenster.overrideredirect(1)
   
    frame=Frame(fenster)
    frame.pack()

    for _row in range(50):
        for _column in range(70):
            print
            l=Label(frame, width=2, bg='white')
            l.grid(row=_row, column=_column)
Sprich, ich habe eine 'print'-Anweisung mit in die Schleife eingebaut, damit funktioniert es auch; Nach und Nach kann man zusehen, wie jeder Würfel platziert wird. Da aber eine 'print'-Anweisung meiner Meinung nach nicht das ist, was ich suche und unprofessionell ist, habe ich 'thread' benutzt.
Vielleicht sind meine Hintergründe jetzt besser zu verstehen^^

Grüße Markus :-)
Antworten