<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Thread-Probleme im Release - Mode]]></title><description><![CDATA[<p>Hallo liebes Forum,</p>
<p>wieder mal eine Frage:</p>
<p>Während meine Anwendung im debug-Mode tadellos funktioniert, habe ich im release-mode mit dem workerthread nur Probleme.</p>
<p>Das Problem tritt beim beenden des threads auf (es läuft weiter).<br />
Die Anwendung läuft als &quot;Zombie&quot; selbst beim beenden des Programms weiter.</p>
<p>Schalte ich in den Projekt-Einstellungen von NDEBUG auf _DEBUG um und manipuliere ein bischen an den Bibliothekseinstellungen funktioniert die<br />
&quot;Pseude - Release - Version&quot;.</p>
<p>Ich versuche mal hier kurz zu erklären, was ich mache.</p>
<p>Hier ist eine FormView - Klassen - Deklaration, in dem der workerthread aktiv ist</p>
<pre><code class="language-cpp">...  
 UINT wait4state();
	static UINT thread_entry(LPVOID lpvoid) 
	{        
		return static_cast&lt;CBpViewSoundPlay*&gt;(lpvoid)-&gt;wait4state();    
	}
	void updateLstCtrl(int, int, const char*, const char*, const char*, const char*);
	void run() 
	{        
		TRACE0(&quot;RUN()\n&quot;);
		m_hStopThread	 = CreateEvent(0, FALSE, FALSE, &quot;StopThread&quot;);
		m_hThreadStopped = CreateEvent(0, FALSE, FALSE, &quot;ThreadStopped&quot;);
		::AfxBeginThread(thread_entry, this);
		TRACE0(&quot;END RUN()\n&quot;);
	} 
	void stop()
	{
		TRACE0(&quot;STOP()\n&quot;);
		if ( m_hThreadStopped ) 
		{
			ASSERT(SetEvent(m_hStopThread));

			MSG   msg;

			while ( true )
			{
				DWORD dwResult = WaitForSingleObject( m_hThreadStopped, 0 );

				if ( dwResult == WAIT_OBJECT_0 )
				{
					// Thread hat sich beendet
					break;
				}
				if ( PeekMessage( &amp;msg, NULL, 0, 0, PM_NOREMOVE ) )
				{
					GetMessage( &amp;msg, 0, 0, 0 );
					TranslateMessage( &amp;msg );
					DispatchMessage( &amp;msg );
				}
			}
		}
		TRACE0(&quot;END STOP()\n&quot;);
	}
	HANDLE	m_hStopThread;
	HANDLE	m_hThreadStopped;
</code></pre>
<p>In der Implementation aktualisiere ich zyklisch in einem Thread eine ListView.<br />
Beim Bedienen eine Dialogbar im MDI soll das Thread sich beenden und ein neues Thread sich starten.</p>
<pre><code class="language-cpp">//-----------------------------------------------------------------------------
LONG CBpViewSoundPlay::OnReInit(UINT, LONG)
{
	char* pszIp = static_cast&lt;CBpApp*&gt;(AfxGetApp())-&gt;m_pszIp;
	if ( pszIp )
	{
		stop();
		m_lctlLoc.DeleteAllItems();
		fillLbLoc(pszIp);
		m_lctlState.DeleteAllItems();
		run();
	}
	return 0L;
}
//-----------------------------------------------------------------------------
</code></pre>
<p>Das funktioniert auch im Debug mode tadellos, nur nicht im Release - Modus.<br />
Beim beenden arbeite ich mit Events und WaitForSingleObject</p>
<p>Die ist ein Teil der Implementation:</p>
<pre><code class="language-cpp">//-----------------------------------------------------------------------------
UINT CBpViewSoundPlay::wait4state()
{
	Database db;

	if ( db.connect(m_csConnectStr) )
	{
		while ( true )
		{
... mache ganz schön viel
// Lese aus der Datenbank und aktualisiere eine ListView
...
			if ( WaitForSingleObject(m_hStopThread, 0) == WAIT_OBJECT_0 )
			{
				SetEvent(m_hThreadStopped);
				break;
			}
		}
		db.disconnect();
	}
	else
		m_hThreadStopped = 0;

	return 0;
}
//-----------------------------------------------------------------------------
</code></pre>
<p>Es fällt mir etwas schwer die Logik verständlich zu erklären.<br />
Es funktioniert etwa so (es ist die bewährte Thread - Logik mit Events):</p>
<p>Das Thread wird gestartet:</p>
<p>...</p>
<p>Im thread wird das Event m_hStopThread mit WaitForSingleObject abgefragt.</p>
<p>Soll das Thread beendet werden, so wird dieses Event vom Hauptprogramm gesetzt mit SetEvent. Das Hauptprogramm wartet wiederum auf die Bestätigung, ob das Thread beendet wird/wurde mit WaitForSingleObject. Hier wird auf das Event<br />
m_hThreadStopped gewartet. Dies wird in der Thread - Funktion mit SetEvent<br />
gesetzt. Erst dann gibt das Hauptprogramm wenn gewünscht die Resourcen frei bzw. initialisiert ein anderes Thread.</p>
<p>So die Theorie, die leider nur im debug - Mode (bei mir läuft).</p>
<p>Über jeden Tipp/Hilfe wäre ich dankbar.</p>
<p>Viele Grüße</p>
<p>Uli2</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/181017/thread-probleme-im-release-mode</link><generator>RSS for Node</generator><lastBuildDate>Sat, 18 Apr 2026 01:17:21 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/181017.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 09 May 2007 09:44:44 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Thread-Probleme im Release - Mode on Wed, 09 May 2007 09:44:44 GMT]]></title><description><![CDATA[<p>Hallo liebes Forum,</p>
<p>wieder mal eine Frage:</p>
<p>Während meine Anwendung im debug-Mode tadellos funktioniert, habe ich im release-mode mit dem workerthread nur Probleme.</p>
<p>Das Problem tritt beim beenden des threads auf (es läuft weiter).<br />
Die Anwendung läuft als &quot;Zombie&quot; selbst beim beenden des Programms weiter.</p>
<p>Schalte ich in den Projekt-Einstellungen von NDEBUG auf _DEBUG um und manipuliere ein bischen an den Bibliothekseinstellungen funktioniert die<br />
&quot;Pseude - Release - Version&quot;.</p>
<p>Ich versuche mal hier kurz zu erklären, was ich mache.</p>
<p>Hier ist eine FormView - Klassen - Deklaration, in dem der workerthread aktiv ist</p>
<pre><code class="language-cpp">...  
 UINT wait4state();
	static UINT thread_entry(LPVOID lpvoid) 
	{        
		return static_cast&lt;CBpViewSoundPlay*&gt;(lpvoid)-&gt;wait4state();    
	}
	void updateLstCtrl(int, int, const char*, const char*, const char*, const char*);
	void run() 
	{        
		TRACE0(&quot;RUN()\n&quot;);
		m_hStopThread	 = CreateEvent(0, FALSE, FALSE, &quot;StopThread&quot;);
		m_hThreadStopped = CreateEvent(0, FALSE, FALSE, &quot;ThreadStopped&quot;);
		::AfxBeginThread(thread_entry, this);
		TRACE0(&quot;END RUN()\n&quot;);
	} 
	void stop()
	{
		TRACE0(&quot;STOP()\n&quot;);
		if ( m_hThreadStopped ) 
		{
			ASSERT(SetEvent(m_hStopThread));

			MSG   msg;

			while ( true )
			{
				DWORD dwResult = WaitForSingleObject( m_hThreadStopped, 0 );

				if ( dwResult == WAIT_OBJECT_0 )
				{
					// Thread hat sich beendet
					break;
				}
				if ( PeekMessage( &amp;msg, NULL, 0, 0, PM_NOREMOVE ) )
				{
					GetMessage( &amp;msg, 0, 0, 0 );
					TranslateMessage( &amp;msg );
					DispatchMessage( &amp;msg );
				}
			}
		}
		TRACE0(&quot;END STOP()\n&quot;);
	}
	HANDLE	m_hStopThread;
	HANDLE	m_hThreadStopped;
</code></pre>
<p>In der Implementation aktualisiere ich zyklisch in einem Thread eine ListView.<br />
Beim Bedienen eine Dialogbar im MDI soll das Thread sich beenden und ein neues Thread sich starten.</p>
<pre><code class="language-cpp">//-----------------------------------------------------------------------------
LONG CBpViewSoundPlay::OnReInit(UINT, LONG)
{
	char* pszIp = static_cast&lt;CBpApp*&gt;(AfxGetApp())-&gt;m_pszIp;
	if ( pszIp )
	{
		stop();
		m_lctlLoc.DeleteAllItems();
		fillLbLoc(pszIp);
		m_lctlState.DeleteAllItems();
		run();
	}
	return 0L;
}
//-----------------------------------------------------------------------------
</code></pre>
<p>Das funktioniert auch im Debug mode tadellos, nur nicht im Release - Modus.<br />
Beim beenden arbeite ich mit Events und WaitForSingleObject</p>
<p>Die ist ein Teil der Implementation:</p>
<pre><code class="language-cpp">//-----------------------------------------------------------------------------
UINT CBpViewSoundPlay::wait4state()
{
	Database db;

	if ( db.connect(m_csConnectStr) )
	{
		while ( true )
		{
... mache ganz schön viel
// Lese aus der Datenbank und aktualisiere eine ListView
...
			if ( WaitForSingleObject(m_hStopThread, 0) == WAIT_OBJECT_0 )
			{
				SetEvent(m_hThreadStopped);
				break;
			}
		}
		db.disconnect();
	}
	else
		m_hThreadStopped = 0;

	return 0;
}
//-----------------------------------------------------------------------------
</code></pre>
<p>Es fällt mir etwas schwer die Logik verständlich zu erklären.<br />
Es funktioniert etwa so (es ist die bewährte Thread - Logik mit Events):</p>
<p>Das Thread wird gestartet:</p>
<p>...</p>
<p>Im thread wird das Event m_hStopThread mit WaitForSingleObject abgefragt.</p>
<p>Soll das Thread beendet werden, so wird dieses Event vom Hauptprogramm gesetzt mit SetEvent. Das Hauptprogramm wartet wiederum auf die Bestätigung, ob das Thread beendet wird/wurde mit WaitForSingleObject. Hier wird auf das Event<br />
m_hThreadStopped gewartet. Dies wird in der Thread - Funktion mit SetEvent<br />
gesetzt. Erst dann gibt das Hauptprogramm wenn gewünscht die Resourcen frei bzw. initialisiert ein anderes Thread.</p>
<p>So die Theorie, die leider nur im debug - Mode (bei mir läuft).</p>
<p>Über jeden Tipp/Hilfe wäre ich dankbar.</p>
<p>Viele Grüße</p>
<p>Uli2</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1281410</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1281410</guid><dc:creator><![CDATA[uli2]]></dc:creator><pubDate>Wed, 09 May 2007 09:44:44 GMT</pubDate></item><item><title><![CDATA[Reply to Thread-Probleme im Release - Mode on Wed, 09 May 2007 10:02:01 GMT]]></title><description><![CDATA[<p>Du kannst nicht nur auf Events warten, sondern z.B. auch auf Thread-Handles (und ein Thread-Handle wird genau dann aktiv, wenn der Thread (wirklich endgültig) beendet ist). Das erspart dir einen Event zur Rückmeldung des Thread-Endes und außerdem verhindert es, daß du zwischen dem SetEvent() und dem db.disconnect() noch unterbrochen wirst.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1281426</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1281426</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Wed, 09 May 2007 10:02:01 GMT</pubDate></item><item><title><![CDATA[Reply to Thread-Probleme im Release - Mode on Wed, 09 May 2007 11:58:25 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>vielen Dank für die prompte Antwort.<br />
Ich habe dies jetzt mal experimentell eingebaut. Leider funktioniert es immer noch nicht.</p>
<p>Hier ist mein Code:</p>
<pre><code class="language-cpp">...
	UINT wait4state();
	static UINT thread_entry(LPVOID lpvoid) 
	{        
		return static_cast&lt;CBpViewSoundPlay*&gt;(lpvoid)-&gt;wait4state();    
	}
	void updateLstCtrl(int, int, const char*, const char*, const char*, const char*);
	void run() 
	{        
		m_hStopThread		= CreateEvent(0, FALSE, FALSE, &quot;StopThread&quot;);
		CWinThread* pThread = ::AfxBeginThread(thread_entry, this);
		m_hThread			= pThread-&gt;m_hThread;
	} 
	void stop()
	{
		ASSERT(SetEvent(m_hStopThread));
		WaitForSingleObject( m_hThread, INFINITE );
	}
	HANDLE  m_hThread;
	HANDLE	m_hStopThread;
...
</code></pre>
<p>und in der Implementation:</p>
<pre><code class="language-cpp">//-----------------------------------------------------------------------------
UINT CBpViewSoundPlay::wait4state()
{
	Database db;

	if ( db.connect(m_csConnectStr) )
	{
		while ( true )
		{
...
// mache ganz schön viel
...
			if ( WaitForSingleObject(m_hStopThread, 0) == WAIT_OBJECT_0 )
				break;
		}
		db.disconnect();
	}

	return 0;
}
//-----------------------------------------------------------------------------
</code></pre>
<p>Die Threadfunktion kehrt nicht zurück, also beendet sich nicht.</p>
<p>Viele Grüße</p>
<p>uli2</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1281531</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1281531</guid><dc:creator><![CDATA[uli2]]></dc:creator><pubDate>Wed, 09 May 2007 11:58:25 GMT</pubDate></item><item><title><![CDATA[Reply to Thread-Probleme im Release - Mode on Wed, 09 May 2007 12:06:36 GMT]]></title><description><![CDATA[<p>Ich empfehle mal den Debugger - wo läuft die Thread-Funktion lang, nachdem du den Stop-Event ausgelöst hast? (vielleicht dauert das &quot;mache ganz schön viel&quot; einfach so lange, daß er nichts von der Unterbrechung mitbekommen hat)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1281538</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1281538</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Wed, 09 May 2007 12:06:36 GMT</pubDate></item><item><title><![CDATA[Reply to Thread-Probleme im Release - Mode on Wed, 09 May 2007 12:58:37 GMT]]></title><description><![CDATA[<p>Hallo CStoll,</p>
<p>Das Hauptprogramm bleibt stehen, und zwar bei dem<br />
WaitForSingleObject(m_hThread, INFINITE)</p>
<p>Setze ich den 2. Parameter auf 1s, also 1000, so funktioniert es meistens.</p>
<p>Ich habe jetzt erstmal meine Variante mit den Events reaktiviert.<br />
In dieser Variante funktioniert wenigstens die debug - Version.<br />
Hier hängt alles an den defines _DEBUG bzw. NDEBUG.<br />
Also eine release - Variante mit _DEBUG funktioniert auch.<br />
Vielleicht liegt es an den speziellen &quot;new&quot; - Operator im debug-Modus.</p>
<p>Ich habe momentan kein Plan, was ich noch machen kann.<br />
Es gibt wohl auch noch Mutexe und CriticalSections, die man verwenden kann.</p>
<p>Vielleicht sollte ich auch das Stück Code mit PeekMessage/GetMessage drin lassen.</p>
<p>Trotzdem erstmal danke.</p>
<p>Grüße</p>
<p>uli2</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1281601</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1281601</guid><dc:creator><![CDATA[uli2]]></dc:creator><pubDate>Wed, 09 May 2007 12:58:37 GMT</pubDate></item></channel></rss>