Problem CreateThread und Python 2.6

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
makro
User
Beiträge: 25
Registriert: Sonntag 12. Juli 2009, 08:53

hallo,
der folgende Code funktioniert unter Python 2.5 einwandfrei. habe nun Python 2.6 installiert. Beim Ausführen von CreateThread stürzt Python komplett ab! Kann mir jemand weiterhelfen, was sich da geändert oder an was das liegen könnte??

Code: Alles auswählen

...
THREAD_PROC = ctypes.WINFUNCTYPE(ctypes.c_uint32,ctypes.c_void_p);

__CreateThread = ctypes.windll.kernel32.CreateThread;

ThreadId = ctypes.c_uint32(0);
hThread = None;


ThreadArg= 0;
    
hThread = __CreateThread(None,0,THREAD_PROC(Thread123),ThreadArg,0,ctypes.byref(ThreadId));
...

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

Na dann mal auf zur munteren Fragerunde: Was heißt "Python stürzt komplett ab"? Wie äußert sich das, gibt es vielleicht eine Fehlermeldung? Andere Hinweise, die zur Eingrenzung des Fehlers führen könnten (logs etc.)?
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Meine erste Frage wäre, warum nutzt Du die WinAPI, wo es doch eine schöne Python-Abstraktion mit threading gibt?
Darf man fragen, wo Du den Code her hast? Die Semikola sind etwas seltsam ;)
makro
User
Beiträge: 25
Registriert: Sonntag 12. Juli 2009, 08:53

hallo,

ja, es kommt eine typische Windows-Fehlermeldung:
"Die Anweisung in 0x00f20fdf verweist auf Speicher 0x00000000. Der Vorgang "written" konnte nicht auf dem Speicher durchgeführt werden.

Warum ich den Thread so erzeuge, wäre jetzt einfach zu lang zum erklären...es muss auch dieser Weg funktionieren bzw. tat es ja bis jetzt auch mit Python 2.5
Das mit Semikolons kommt daher, weil ich eben alter C-Programmierer bin und es einfach eine Angewohnheit ist :)
BlackJack

Kannst Du ein minimales, lauffähiges Beispiel zeigen? Sonst kann man das ja schlecht nachvollziehen.
makro
User
Beiträge: 25
Registriert: Sonntag 12. Juli 2009, 08:53

Code: Alles auswählen


import ctypes
from win32api import *

THREAD_PROC = ctypes.WINFUNCTYPE(ctypes.c_uint32,ctypes.c_void_p);

__CreateThread = ctypes.windll.kernel32.CreateThread;


ThreadArg=0;

ThreadId = ctypes.c_uint32(0);

# *************************************************************************************
def Thread1(arg):

    i=0;
    while(i<10):
        print i
        Sleep(1000);
        i += 1;

    return 0;        

# *************************************************************************************

hThread = __CreateThread(None,0,THREAD_PROC(Thread1),ThreadArg,0,ctypes.byref(ThreadId));

# *************************************************************************************

das kann man so wie es ist, z.b. in Pythonwin ausführen
BlackJack

In der `ctypes`-Dokumentation steht im Abschnitt Callback functions folgender Hinweis:
Important note for callback functions:
Make sure you keep references to CFUNCTYPE objects as long as they are used from C code. ctypes doesn’t, and if you don’t, they may be garbage collected, crashing your program when a callback is made.
Sollte es das gewesen sein?
makro
User
Beiträge: 25
Registriert: Sonntag 12. Juli 2009, 08:53

nein..glaub ich nicht...weil wenn man wie oben den code ausführt, die referenz vorher nicht wieder aufgelöst wird..man kann ja noch ein print reinmachen, da sieht man´s ja dann...

es funktioniert ja unter Python 2.5..der einzigste unterschied zu jetzt ist, dass ich Python 2.6 installiert habe..
BlackJack

@makro: Also erst einmal ist das was Du da machst auf den Hinweis in der Doku bezogen auf jeden Fall falsch. Du behältst nirgends eine Referenz auf das Objekt und genau davor wird in der Doku gewarnt!

Gerade bei Thread-Problemen ist "Aber mit Version XY lief das, also muss es richtig sein." kein gutes Argument. Man kann auch einfach nur Glück gehabt haben, dass die Version etwas subtil anders macht und die eigenen Programmfehler deswegen nicht zum Vorschein kommen.
makro
User
Beiträge: 25
Registriert: Sonntag 12. Juli 2009, 08:53

hallo,

ich seh das bissle anders...weil das Objekt "CreateThread" global in einem Skript angelegt ist..und wenn dieses skript durch eine import-anweisung geladen wird, wird auch dieses objekt angelegt und bleibt über laufzeit des programms erhalten..
BlackJack

@makro: Um das Objekt geht es doch gar nicht, sondern um das Objekt das die "callback"-Funktion repräsentiert. Das was vom Aufruf von `THREAD_PROC()` zurückgegeben wird. Das wird nirgends gebunden und könnte sofort nach der Rückkehr des Aufrufs von `__CreateThread()` wieder freigegeben werden. Da kann es durchaus passieren das der Thread diese Funktion noch nicht aufgerufen hat.
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Ja es fehlt die Referenz von THREAD_PROC(Thread1). So funktioniert es:

Code: Alles auswählen

...
whatever = THREAD_PROC(Thread1)
...
hThread = __CreateThread(None,0,whatever,ThreadArg,0,ctypes.byref(ThreadId))
...
Antworten