Meine Threads arbeiten nicht simultan

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
PythonFan_FFM
User
Beiträge: 3
Registriert: Freitag 30. Januar 2009, 11:53

Hallo,
ich versuche mich gerade ein bisschen an Threads heranzuarbeiten.
Dabei habe ich ein sehr einfaches Beispiel geschrieben.
Es geht mir darum, dass zwei Threads gleichzeitig bis 10 Zählen sollen.

Ich habe folgendes geschrieben:

Code: Alles auswählen

import threading

class MyThread (threading.Thread):
    def __init__(self, name):
        threading.Thread.__init__(self) 
        self.name = name
    def start(self):
        for i in range(10):
            print self.name
            
thread1 = MyThread("Thread_1")
thread2 = MyThread("Thread_2")
thread1.start()
thread2.start()
Ich würde jetzt erwarten, dass irgendwie mal Thread_1 und mal Thread_2 an die Reihe kommt und seinen Namen ausgibt.
Dies ist nicht der Fall; beide arbeiten nach einander.
Kann mir jemand sagen was ich falsch mache?
Oder habe ich da was grundsätzliches nicht verstanden?

Gruß,
PythonFan
Benutzeravatar
helduel
User
Beiträge: 300
Registriert: Montag 23. Juli 2007, 14:05
Wohnort: Laupheim

Moin,

mach auch der start-Methode eine run-Methode (das wird in einem Thread ausgeführt) und füg einfach ein time.sleep in deine Schleife mit ein. Dann geht's und durch das time.sleep wird's deutlicher sichtbar.

Gruß,
Manuel
Pekh
User
Beiträge: 482
Registriert: Donnerstag 22. Mai 2008, 09:09

Letzteres: Du kannst die Reihenfolge, in der die Threads aufgerufen werden nicht beeinflussen. Darum kümmern sich Betriebssystem und CPU. Folglich kann es durchaus passieren, daß die beiden Threads nacheinander drankommen.
Zweitens ist das Runterzählen einer so kleinen Schleife offenbar innerhalb einer Zeitscheibe zu erledigen: Um den gewünschten Effekt zu erzielen, müßtest du nach jeder Ausgabe dem Betriebssystem mitteilen, daß dein Thread jetzt die Kontrolle an einen anderen Thread abgeben möchte. Das Kommando kenne ich jetzt gerade nicht, aber suche mal nach 'yield' oder ähnlichem.
PythonFan_FFM
User
Beiträge: 3
Registriert: Freitag 30. Januar 2009, 11:53

Danke für eure Antworten. Aber irgendwas stimmt da immer noch nicht.
Ich habe das Skript jetzt ein bisschen modifiziert, und es sieht nun so aus:

Code: Alles auswählen

import threading
import time
g=0
class MyThread (threading.Thread):
    def __init__(self, name):
        threading.Thread.__init__(self) 
        self.name = name
    def run(self):
        for i in range(10):
            time.sleep(1)
            print i,self.name
            
thread1 = MyThread("Thread_1")
thread2 = MyThread("Thread_2")
thread1.run()
thread2.run()
Jetzt müsste doch in der Pause von 1 Sekunde die jeder Thread schläft, eigentlich der andere weiterarbeiten, oder?
Ich habe auch schon 5 Sekunden Pausen gemacht, und jedes mal
arbeitet erst Thread 1 alles ab, dann Thread 2.

Wenn ich jetzt jedem Thread sage, dass er danach die Kontrolle an einen anderen Thread abgeben soll, dann brauch ich doch auch keine Threads oder? - Dann kann ich auch gleich alles als eine normale Funktion implementieren.

Kann mir vielleicht jemand sagen, was ich immer noch falsch mache/verstehe?

Danke!
Gruß,
PythonFan
Benutzeravatar
helduel
User
Beiträge: 300
Registriert: Montag 23. Juli 2007, 14:05
Wohnort: Laupheim

Threads werden mit der start-Methode gestartet.

Code: Alles auswählen

import threading
import time
g=0
class MyThread (threading.Thread):
    def __init__(self, name):
        threading.Thread.__init__(self)
        self.name = name
    def run(self):
        for i in range(10):
            time.sleep(1)
            print i,self.name
           
thread1 = MyThread("Thread_1")
thread2 = MyThread("Thread_2")
thread1.start()
thread2.start()
So sollte es gehen.
PythonFan_FFM
User
Beiträge: 3
Registriert: Freitag 30. Januar 2009, 11:53

Danke für die Antwort.

Wenn ich den Code so wie du ihn mir geschrieben hast ausführe, dann stürzt mein Python einfach ab.
Kein aufhängen oder so, es kommt einfach ein "pythonw.exe hat ein Problem festgestellt und muss beendet werden." und das wars.

Ich nutze Python 2.5.1. Windows MCE.

Weiß jemand warum das jetzt auf einmal absürzt??
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Bei mir läuft's und die Threads werden parallel abgearbeitet. Python 2.4 auf Windows XP.
MfG
HWK
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

PythonFan_FFM hat geschrieben:Ich nutze Python 2.5.1. Windows MCE.
Weiß jemand warum das jetzt auf einmal absürzt??
Muss an deiner Installation liegen. Prinzipiell läuft es und bestimmt auch unter Windows. Du könntest es ja mal mit dem aktuelleren CPython 2.6 versuchen, denn vielleicht ist deine Installation kaputt.

Übrigens wirst du in CPython bei diesem Beispiel auch auf einem Rechner mit mehreren Prozessor(kernen) keine echte Parallelität bekommen. Bei CPython kann immer nur ein Python-Thread gleichzeitig laufen. Diese Beschränkung nennt sich GIL (Global Interpreter Lock).

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

Für echte parallele Prozesse gibts ab Python 2.6 das Modul multiprocessing, damit geht paralleles Arbeiten ziemlich einfach.

Gruss
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

sma hat geschrieben: Übrigens wirst du in CPython bei diesem Beispiel auch auf einem Rechner mit mehreren Prozessor(kernen) keine echte Parallelität bekommen. Bei CPython kann immer nur ein Python-Thread gleichzeitig laufen. Diese Beschränkung nennt sich GIL (Global Interpreter Lock).
Das ist so irreführend. Es können durchaus mehrere Python-Threads gleichzeitig laufen. Es kann nur jeweils einer Python-(Byte-)Code ausführen. Während low-level-calls auf C-Ebene (wie zum Beispiel das sleep()) ausgeführt werden, kann ein anderer Thread laufen.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Antworten