PostMessage() nach DestroyWindow(): Undefiniertes Verhalten?
-
Für rein Flag vom Typ bool oder Integer ist höchstens das Keywort volatile notwendig. Weder InterlockExchange noch CriticalSection. Warum auch?
-
hustbaer schrieb:
Was SendMessage angeht, gebe ich Dir recht, allerdings gibt IMHO im Aplication Verifier einen Break, wenn ein Handle verwendet wird, das nciht existiert!
Durch ein Certified for xyz würde die Anwendung dann durchfallen.Mag sein, ich hab noch nie eine Anwendung verifizieren lassen. Ist aber total bescheuert, weil wie gesagt das nötige "if" ja schon in SendMessage steckt.
Nein tut es nicht. Wenn z.B. Hooks installiert werden oder OLE läuft (STA läuft über die Message Queue) dann greifen intern Mechanismen, die es z.T. nicht mögen, dass Nachrichten an Fenster gesandt werden, die 1. Nicht existieren oder 2. nicht mehr existieren.
-
Höchstens volatile. Und wann?
Ich dachte, man muss einen Zugriff aus mehreren Threads synchronisieren.
So wie ich @hustbaer verstanden habe, sollte ich synchronisieren.
-
hustbaer hat nichts dergleichen gesagt...
Du hast ein Flag abort. Das soll geprüft werden...
Wenn es gesetzt ist Abbruch, wenn nicht ein neuer Schleifendurchlauf?
Was soll hier eine Schutz der Variable?
Was denkst Du denn was anders wird?CriticalSection müssen verwendet werden wenn Wertepaare/gruppen maipuliert werden.
volatile sagt dem Compiler, dass diese Variable, von extern (anderer Thread) geändert werden kann. Der Compiler darf also diese Variable nicht optimieren.
-
Destroy0r schrieb:
Höchstens volatile. Und wann?
Ich dachte, man muss einen Zugriff aus mehreren Threads synchronisieren.
So wie ich @hustbaer verstanden habe, sollte ich synchronisieren.Du musst den Zugriff durch eine Mutex oder eine Semaphore synchronisieren. Was Martin meinte gilt nur für gemeinsamen Lesezugriff. Bei gemeinsamen Schreibzugriff muss die Synchronisation erfolgen, da sonst Inkonsistenzen entstehen können, da ja auf Assemblerebene die Variable zuerst in ein Prozessorregister gelesen werden muss, es also keine atomare Operation ist, sondern 3 oder mehr Maschinenbefehle.
-
hustbaer schrieb:
atomb0mb3 schrieb:
Destroy0r schrieb:
Ne, die ist nicht unnötig, weil "abort" im Hauptthread auf "true" gesetzt wird, und zwar bevor dort DestroyWindow() aufgerufen wird.
Und sobald eine Variable in zwei Threads verwendet wird, muss doch synchronisiert werden.nö es ist eine atomare operation
Nicht auf jeder CPU, und nicht jede Variable.
Und generell auch nur, wenn das Alignment passt, was wiederum nicht jeder Compiler garantieren muss.Mal ganz davon abgesehen dass der C++ Standard diesbezüglich garkeine Garantien abgibt, weil er (noch) kein Speichermodell vorschreibt, und keine Threads kennt.
Oh Mann! *VERWIRRUNG*
Ein reiner Lesezugriff muss nicht synchronisiert werden? Ich hab mich zwar auch immer gewundert, warum es so sein sollte, allerdings las ich bis jetzt immer, dass man auch da synchronisieren muss!
Nun, in meinem Fall gibt es aber auch einen Schreibzugriff.
@Martin Richter
Das Flag kann im Hauptthread auf true gesetzt werden. Im Downloadthread wird es eigentlich nur abgefragt.Und nun? Brauche ich nun eine Synchronisation?
Was meinst du mit Wertepaare/gruppen?
Martin Richter schrieb:
Für rein Flag vom Typ bool oder Integer ist höchstens das Keywort volatile notwendig. Weder InterlockExchange noch CriticalSection. Warum auch?
Lies was @hustbaer geschrieben hat. Demnach ist das Schreiben/Lesen eines bool/int nicht zwingend atomar, also muss ich es doch synchronisieren?
Ich verzweifle...
-
Destroy0r schrieb:
Oh Mann! *VERWIRRUNG*
Ein reiner Lesezugriff muss nicht synchronisiert werden? Ich hab mich zwar auch immer gewundert, warum es so sein sollte, allerdings las ich bis jetzt immer, dass man auch da synchronisieren muss!
Nun, in meinem Fall gibt es aber auch einen Schreibzugriff.
@Martin Richter
Das Flag kann im Hauptthread auf true gesetzt werden. Im Downloadthread wird es eigentlich nur abgefragt.Und nun? Brauche ich nun eine Synchronisation?
Nein!
1. Sorgt der Compiler für "normale" int/bool immer für ein korrektes Alignement.
2. Wen stört es ob dasschreiben, der Variable 1ms vor oder nach dem Lesen der Variable erfolgt.
3. Hast Du eher ein Problem der Sichtbarkeit der Änderung in multi core Maschinen. Sprich "Memory Barrier". Hier helfen die Interlock Funktionen.Destroy0r schrieb:
Was meinst du mit Wertepaare/gruppen?
So schwer?
Thread 1: Erhöht Zäler und addiert Wert in eine Summe
Thread 2: Dividiert Summe durch Zähler.
Das Paar darf immer nur atomar gelesen und geschrieben werden.
Wir haben ein Wertepaar, das durch eine CriticalSection geschützt werden muss. Die Interlock Funktionen helfen nicht.Destroy0r schrieb:
Martin Richter schrieb:
Für rein Flag vom Typ bool oder Integer ist höchstens das Keywort volatile notwendig. Weder InterlockExchange noch CriticalSection. Warum auch?
Lies was @hustbaer geschrieben hat. Demnach ist das Schreiben/Lesen eines bool/int nicht zwingend atomar, also muss ich es doch synchronisieren?
Ich verzweifle...
Wenn überhaupt langen die Interlock Funktionen um die Sichtbarkeit zu gewährleisten auf Multicore Maschinen. Aber selbst das ist in Deinem Fall ein Witz, weil Du genug OS Zugriffe machen, die Memory Barriers sind.
volatile ist hier eher von Nöten, die dem Compiler sagt, dass er hier nur eingeschränkt optimieren darf. Aber selbst dieses Schlüsselwort ist in den MS Compilern ni9cht nötig (was nicht heißt, dass man es ignorieren sollte).
Für "normale" Variablen int/bool, sorgt der Compiler für korrektes Alignment. Außer Du kalkulierst Dir einen Speicher zusammen.
Siehe auch MemoryBarrier:
http://msdn.microsoft.com/en-us/library/ms684208(VS.85).aspx
-
Was hat das jetzt mit einem oder mehr Kernen zu tun?
Schade, ich kapier wieder nix!
Irgendwie hab ich das Gefühl, dass ihr mich alle absichtlich verwirrt!
Oder ich bin einfach zu dumm!Weißt du, Martin, ein paar einfache Sätze wie "Bei MS Compilern brauchst du bei einem integer read/write entweder volatile, oder ein MemoryBarrier Makro, aber eigentlich geht es auch ohne"...
oder so in der Art, das würde mir mal helfen. Naja...
-
Destroy0r schrieb:
Was hat das jetzt mit einem oder mehr Kernen zu tun?
Schade, ich kapier wieder nix!
Irgendwie hab ich das Gefühl, dass ihr mich alle absichtlich verwirrt!
Oder ich bin einfach zu dumm!1. Evtl. solltest Du Dir einfach mal Gedanken und Lesen machen was Multithreading bedeutet. Insbesondere wenn 2 Kerne und mehr vorhanden sind.
Bzgl. "Memory Barrier".
Wenn ein Prozessor auf den Speicher zugreift, dann cached er diesen Speicher. Was passiert wenn nun ein zweiter Prozessor in diesen Speicher schreibt und kurz danach wieder vom ersten Prozessor gelesen werden soll? Wenn es keine Memory Barrier gibt, dann liest der erste Prozessor wieder aus dem Cache. Eine Memorfy Barrier macht die Änderung des RAMs für andere CPUs "sichtbar".
Weitehin gibt es neckische Probleme mit dem Instruction-Reodering... (Google selbst)
Solche probelme hat eine CPU mit einem Kern gar nicht!2. Habe ich geschrieben was ich für notwendig halte.
3. Enthebt Dich meine Antwort nicht des Verstehens, warum es so ist und die entsprechenden Infos bzw. Stichworte habe ich Dir gegeben.
-
Ich möchte davon ausgehen, dass es mehr als einen Kern gibt.
Also benötige ich nun immer für integer reads/writes ein volatile/Interlocked..() und für alles andere komplette Synchronisation (CriticalSection,...)?