Multithreadingprobleme (Direct3D 9)

Vollbild-Direct3D-Anwendungen stellen ein Fensterhandle für die Direct3D-Laufzeit bereit. Das Fenster wird durch die Laufzeit eingebunden. Dies bedeutet, dass alle Nachrichten, die an die Fensternachrichtenprozedur der Anwendung übergeben werden, zuerst von der eigenen Nachrichtenverarbeitungsprozedur der Direct3D-Laufzeit untersucht wurden.

Änderungen im Anzeigemodus werden von Supportroutinen beeinflusst, die in das zugrunde liegende Betriebssystem integriert sind. Wenn der Modus geändert wird, sendet das System mehrere Nachrichten an alle Anwendungen. In Direct3D-Anwendungen werden die Meldungen im Fensterprozedurthread empfangen, bei dem es sich nicht unbedingt um den thread handelt, der IDirect3DDevice9::Reset oder IDirect3D9::CreateDevice aufgerufen hat (oder das endgültige Release von IDirect3DDevice9, was zu einer Änderung des Anzeigemodus führen kann). Die Direct3D-Laufzeit verwaltet mehrere kritische Abschnitte intern. Da mindestens einer dieser kritischen Abschnitte über den Modusschalter gespeichert wird, der durch IDirect3DDevice9::Reset oder IDirect3D9::CreateDevice verursacht wird, werden diese kritischen Abschnitte weiterhin gespeichert, wenn die Anwendung die Meldungen zu den Modusänderungen empfängt.

Dieser Entwurf hat einige Auswirkungen auf Multithreadanwendungen. Insbesondere muss eine Anwendung sicherstellen, dass ihre Fensternachrichtenverarbeitungsthreads stark von ihren Direct3D-Threads getrennt werden. Eine Anwendung, die einen Moduswechsel in einem Thread verursacht, aber Direct3D-Aufrufe für einen anderen Thread in ihrer Fensterprozedur durchführt, ist vom Deadlock bedroht.

Aus diesen Gründen ist Direct3D so konzipiert, dass die Methoden IDirect3DDevice9::Reset, IDirect3D9::CreateDevice, IDirect3DDevice9::TestCooperativeLevel oder das endgültige Release von IDirect3DDevice9 nur aus demselben Thread aufgerufen werden können, der Fenstermeldungen verarbeitet.

Programmiertipps