<?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[Verwendung von CCriticalSection]]></title><description><![CDATA[<p>Hi Leute,</p>
<p>ich hätte da eine Frage bezüglich CriticalSetions.<br />
Zum Ablauf:<br />
ein Workerthread liest von der seriellen Schnittstelle ein Wort (2Bytes hintereinander) in ein inBuf ein.<br />
Die Methode synchronize() stellt fest, ob gerade ein neuer Datenblock mit Header usw beginnt.<br />
decodeInput holt schliesslich die Nutzdaten, die für den Hauptthread relevant sind.</p>
<p>Meine Frage lautet nun:</p>
<p>Wie synchronisiere ich den Zugriff auf die globale Variablenstruktur &quot;dbgMonData&quot;? Muß ich da im Hauptthread auch alle Stellen, wo ich auf dieselbe Variable zugreifen will, in ein CriticalSection verpacken?</p>
<p>hier der Codeabschnitt im Workerthread:</p>
<pre><code class="language-cpp">UINT ThreadProc (LPVOID pParam)
{
	CPlotterDlg* pDlg = (CPlotterDlg*) pParam;

	while(true)
	{
		if (pDlg-&gt;synchronize() == true)
		{
			pDlg-&gt;decodeInput();
		}
		// schlafen, damit der Thread nicht 100% Rechenleistung beansprucht
		Sleep(1);
	}

	return 0;
}

// liest 2 Bytes aus dem UART-Buffer und erstellt ein Wort daraus (16 Bit)
bool CPlotterDlg::readRS232Word(WORD *data)
{
	ReadFile(hComm, byteInBuf, 2, &amp;dwBytesRead, NULL);
	*data = (((WORD)byteInBuf[0]) &lt;&lt; 8) + (WORD)byteInBuf[1];
	return true;
}

bool CPlotterDlg::synchronize()
{
	m_CriticalSection.Lock();

	readRS232Word(&amp;dbgMonData.syncWord);
	if (dbgMonData.syncWord == SYNC_WORD)
		return true;
	else
	{
		dbgMonData.syncWord = NULL;
		return false;
	}

	m_CriticalSection.Unlock();
}

void CPlotterDlg::decodeInput()
{
	m_CriticalSection.Lock();

	readRS232Word(&amp;dbgMonData.header);
	readRS232Word(&amp;dbgMonData.length);

	switch (dbgMonData.header)
	{
		case TEAK_TSPP_HDR:
			readRS232Word((WORD *)&amp;dbgMonData.tsppData.DT);
		//	readRS232Word((WORD *)&amp;dbgMonData.tsppData.DT_sum);
			break;
	}

	m_CriticalSection.Unlock();
}
</code></pre>
<p>Danke im voraus</p>
<p>condor</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/72588/verwendung-von-ccriticalsection</link><generator>RSS for Node</generator><lastBuildDate>Mon, 27 Apr 2026 18:16:20 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/72588.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 30 Apr 2004 07:52:22 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Verwendung von CCriticalSection on Fri, 30 Apr 2004 07:52:22 GMT]]></title><description><![CDATA[<p>Hi Leute,</p>
<p>ich hätte da eine Frage bezüglich CriticalSetions.<br />
Zum Ablauf:<br />
ein Workerthread liest von der seriellen Schnittstelle ein Wort (2Bytes hintereinander) in ein inBuf ein.<br />
Die Methode synchronize() stellt fest, ob gerade ein neuer Datenblock mit Header usw beginnt.<br />
decodeInput holt schliesslich die Nutzdaten, die für den Hauptthread relevant sind.</p>
<p>Meine Frage lautet nun:</p>
<p>Wie synchronisiere ich den Zugriff auf die globale Variablenstruktur &quot;dbgMonData&quot;? Muß ich da im Hauptthread auch alle Stellen, wo ich auf dieselbe Variable zugreifen will, in ein CriticalSection verpacken?</p>
<p>hier der Codeabschnitt im Workerthread:</p>
<pre><code class="language-cpp">UINT ThreadProc (LPVOID pParam)
{
	CPlotterDlg* pDlg = (CPlotterDlg*) pParam;

	while(true)
	{
		if (pDlg-&gt;synchronize() == true)
		{
			pDlg-&gt;decodeInput();
		}
		// schlafen, damit der Thread nicht 100% Rechenleistung beansprucht
		Sleep(1);
	}

	return 0;
}

// liest 2 Bytes aus dem UART-Buffer und erstellt ein Wort daraus (16 Bit)
bool CPlotterDlg::readRS232Word(WORD *data)
{
	ReadFile(hComm, byteInBuf, 2, &amp;dwBytesRead, NULL);
	*data = (((WORD)byteInBuf[0]) &lt;&lt; 8) + (WORD)byteInBuf[1];
	return true;
}

bool CPlotterDlg::synchronize()
{
	m_CriticalSection.Lock();

	readRS232Word(&amp;dbgMonData.syncWord);
	if (dbgMonData.syncWord == SYNC_WORD)
		return true;
	else
	{
		dbgMonData.syncWord = NULL;
		return false;
	}

	m_CriticalSection.Unlock();
}

void CPlotterDlg::decodeInput()
{
	m_CriticalSection.Lock();

	readRS232Word(&amp;dbgMonData.header);
	readRS232Word(&amp;dbgMonData.length);

	switch (dbgMonData.header)
	{
		case TEAK_TSPP_HDR:
			readRS232Word((WORD *)&amp;dbgMonData.tsppData.DT);
		//	readRS232Word((WORD *)&amp;dbgMonData.tsppData.DT_sum);
			break;
	}

	m_CriticalSection.Unlock();
}
</code></pre>
<p>Danke im voraus</p>
<p>condor</p>
]]></description><link>https://www.c-plusplus.net/forum/post/511577</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/511577</guid><dc:creator><![CDATA[condor]]></dc:creator><pubDate>Fri, 30 Apr 2004 07:52:22 GMT</pubDate></item><item><title><![CDATA[Reply to Verwendung von CCriticalSection on Fri, 30 Apr 2004 08:42:46 GMT]]></title><description><![CDATA[<p>prinzipell:<br />
Solltest du alles schuetzen, worauf du <strong>lesend</strong> und <strong>schreibend</strong> parallel drauf zugreifen koenntest .</p>
<pre><code class="language-cpp">bool CPlotterDlg::synchronize()
{
    m_CriticalSection.Lock();

    readRS232Word(&amp;dbgMonData.syncWord);
    if (dbgMonData.syncWord == SYNC_WORD)
        return true;
    else
    {
        dbgMonData.syncWord = NULL;
        return false;
    }

    m_CriticalSection.Unlock();
}
</code></pre>
<p>Das wird dir das genick brechen !!!<br />
den lock solltest schon aufheben, bovor die schleife verlaesst . in deinem Code bleibt das object bei austritt gelockt.</p>
<p>Ne elegante Moeglickeit sich diesen Aerger zu sparen ist nen fuer den Lock ne Klasse zu schreiben, die das Locken fuer dich komplett uebernimmt, im konstruktur und destruktor, so dass bei verlassen des Gueltigkeitsbreeiches automatisch entlockst .... Am besten als Tamplate !</p>
<pre><code class="language-cpp">template&lt;class TCS&gt;
class ObjectLock
{
public:
    ObjectLock(TCS &amp; rxCS):
    m_CS(rxCS)
    {
        m_CS.Lock();
    };
    ~ObjectLock
    {
        m_CS.Unlock();
    };
private:
    TCS &amp; m_CS;
}
</code></pre>
<p>Nun brauchst das Template nor noch typisieren, und dem deine CCriticalSection zu uebergeben, und schon entlockt sich die Methode selber ....</p>
<p>irgendwo den Typ definieren ...<br />
typedef ObjectLock&lt;CCriticalSection&gt; ObjectLockT;</p>
<pre><code class="language-cpp">bool CPlotterDlg::synchronize()
{
    // m_CriticalSection.Lock(); 
    // nu das Object locken lassem 
    ObjectLockT myLock(m_CriticalSection);

    readRS232Word(&amp;dbgMonData.syncWord);
    if (dbgMonData.syncWord == SYNC_WORD)
        // hier haette es geknallt, weil rausgehst ohne zu entlocken 
        return true;
    else
    {
        dbgMonData.syncWord = NULL;
        // hier haette es geknallt, weil rausgehst ohne zu entlocken 
        return false;
    }

    // m_CriticalSection.Unlock();
    // Braucht man nu ned mehr ... 
}
</code></pre>
<p>Dadurch dass dein Objectlock nen Template ist, kannst die sache auch objektorientiert besser designen, in dem deiner zu lockenden Klasse die CCriticalsection als member gibts, der Klasse ne eigene Lock und Unlock member funktion speniderst (klasse sollte eh immer die selbe Critical section verwenden) dann kannst die eigene Klasse als Template vorlage verwenden ... und den Lock mit this an die eigene klasse delegieren ...</p>
<pre><code class="language-cpp">// die h. Datei ... 
class CPlotterDlg // was hier sonst noch so kommt ... 
{
    // ... was sonst noch so brauchst .... 
public:
    void Lock(){mcs.Lock();};
    void Unlock(){mcs.Unock();};
private:
    ObjectLock&lt;CPlotterDlg&gt; ObjectLockT;
    CCriticalSection mcs;
};
// nu kannst in jeder Methode ziemlich einfach locken: 
bool CPlotterDlg::synchronize()
{
    ObjectLockT myLock(this);
    // und weiter im Text ... das teil entlockt sich automatisch dann ... 
}
</code></pre>
<p>Deadlocks sind nett zu debuggen .... glaub mir <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f921.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--clown_face"
      title=":clown:"
      alt="🤡"
    /></p>
<p>Ciao ...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/511612</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/511612</guid><dc:creator><![CDATA[RHBaum]]></dc:creator><pubDate>Fri, 30 Apr 2004 08:42:46 GMT</pubDate></item><item><title><![CDATA[Reply to Verwendung von CCriticalSection on Fri, 30 Apr 2004 09:13:49 GMT]]></title><description><![CDATA[<p>Danke ist eine gute Idee mit der eigenen Lock-Klasse, ich werde das mal durchsehen, habe nebenher noch ein paar andere Stellen endeckt, die mit geringfügiger &quot;Optimierung&quot; den Lock überflüssig machen.</p>
<p>nochmals thx</p>
]]></description><link>https://www.c-plusplus.net/forum/post/511627</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/511627</guid><dc:creator><![CDATA[condor]]></dc:creator><pubDate>Fri, 30 Apr 2004 09:13:49 GMT</pubDate></item><item><title><![CDATA[Reply to Verwendung von CCriticalSection on Fri, 30 Apr 2004 09:28:30 GMT]]></title><description><![CDATA[<p>Oh man jetzt erst sehe ich was ich da für einen Mist bei synchronize() gebaut habe,<br />
na ja ist das erste Mal, dass ich mit Synchronisierung arbeite. Danke <a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/3842">@RHBaum</a> für die hervorragende Klassenlösung! Jetzt weiß ich was ich zu tun habe.</p>
<p>Mfg</p>
<p>condor</p>
]]></description><link>https://www.c-plusplus.net/forum/post/511640</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/511640</guid><dc:creator><![CDATA[condor]]></dc:creator><pubDate>Fri, 30 Apr 2004 09:28:30 GMT</pubDate></item><item><title><![CDATA[Reply to Verwendung von CCriticalSection on Fri, 30 Apr 2004 09:48:12 GMT]]></title><description><![CDATA[<p>Die Klassenloesung ist aber ned das nonplus ultra ....</p>
<p>Um so komplizierter dein Aufbau wird, um so weniger kannst sowas nutzen ...</p>
<p>Achten solltest du auch auf folgendes ....</p>
<p>rufe niemals Schnittstellenmothoden(Com+) im gelockten zustand auf.<br />
aquivalent zu normalen C++: rufe niemals funktionen eines Objektes im gelockten zusatend auf, das nicht unter deiner 100%igen kontrolle ist. (Du musst sicher sein, dass dieses Object dich nicht auch wieder aufruft mittels eine Methode die dann Lockt )</p>
<p>Breche das Locking so weit wie meoglich runter. EIne Klasse die keine Members hat, braucht ned locken. eine Klasse die nur Threadsichere members hat, braucht auch ned locken ...<br />
Geht nicht immer, aber wenn, dann schreib Objecte die Dir komplett die Daten halten, mach diese Threadsicher (lock unlock). Damit trennst du logic von den daten, und brauchst nicht bei dem Logic Handling locken ... erspart dir manchmal viel aerger.</p>
<p>Nutze zum Debuggen spezielle CCritical section objecte ... die Dir das Locken raustracen. Das hilft enorm um deadlocks aufzuspueren ! Templates helfen da ungemein ... durch die kannst du schnell die Critical Sections ersetzen ...</p>
<p>noch was zu nem anderem thema ...</p>
<pre><code class="language-cpp">// schlafen, damit der Thread nicht 100% Rechenleistung beansprucht
        Sleep(1);
</code></pre>
<p>Aehm schon der Kommentar deutet auf schlechtes Design hin <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":-)"
      alt="🙂"
    /><br />
Bei Multithreading musst viel sorgsamer mit der rechenleistung umgehen ... und ja keine unnoetigen schleifen !!!<br />
Nutze Events ! bei threads ist das das Mittel der Wahl !<br />
Stichworte ! SetEvent ResetEvent WaitForSingleObject WaitForMultiObject .....</p>
<p>Ciao ...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/511660</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/511660</guid><dc:creator><![CDATA[RHBaum]]></dc:creator><pubDate>Fri, 30 Apr 2004 09:48:12 GMT</pubDate></item><item><title><![CDATA[Reply to Verwendung von CCriticalSection on Fri, 30 Apr 2004 11:26:40 GMT]]></title><description><![CDATA[<p>Das mit dem Sleep(1) habe ich aus einem Buch, ist also nich auf meinem Mist gewachsen, obwohl ich natürlich einsehe, dass Events da besser sind...</p>
<p>mfg<br />
condor</p>
]]></description><link>https://www.c-plusplus.net/forum/post/511739</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/511739</guid><dc:creator><![CDATA[condor]]></dc:creator><pubDate>Fri, 30 Apr 2004 11:26:40 GMT</pubDate></item></channel></rss>