<?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[For loop und pthread]]></title><description><![CDATA[<p>Hallo ihr Lieben,</p>
<p>nach langer Zeit habe ich auch mal wieder eine Frage:</p>
<p>Ich versuche mich gerade am Parallelisieren mittels pthread und möchte dabei direkt ein paar Argumente übergeben.</p>
<p>Hier der Quellcode:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;pthread.h&gt;
#include &lt;string&gt;
#include &lt;vector&gt;

struct DATA {

  DATA(
	  const std::string&amp; s,
		const unsigned int&amp; i):
      dummy( s ), id(i) {};

	const std::string dummy;
	const unsigned int id;
};

void* foo(void* arg) {

	DATA* data = static_cast&lt;DATA*&gt;(arg);

	std::cout &lt;&lt; &quot;Thread Nr. &quot; &lt;&lt; data -&gt; id 
		        &lt;&lt; &quot; gives &quot; &lt;&lt; data -&gt; dummy &lt;&lt; std::endl;

  pthread_exit(NULL);
}

int main() {

  std::vector&lt;std::string&gt; dummies = { &quot;some&quot;,&quot;stuff&quot;,&quot;in&quot;,&quot;here&quot; };

	pthread_t threads[ dummies.size() ];

	for( unsigned int i = 0; i &lt; dummies.size(); ++i ) {

    DATA data( dummies[ i ], i );

    pthread_create( &amp;threads[i], NULL, foo, (void *)&amp;data );
  }

  pthread_exit(NULL);

	return 0;
}
</code></pre>
<p>Der Knackpunkt ist, dass die Ausgabe dabei Müll ist, z.B.</p>
<pre><code>Thread Nr. Thread Nr. 33 gives  gives herehere
3read Nr. Thread Nr. 3 gives hereH,D\�`�&lt;� �&lt;��`��� ����`{&lt;� {&lt;��`k�� k��!�f�f�&lt;�s��f�f�&lt;�s�
</code></pre>
<p>Dabei habe ich mich an <a href="http://www.tutorialspoint.com/cplusplus/cpp_multithreading.htm" rel="nofollow">diesem Beispiel</a> orientiert.</p>
<p>Jetzt kommt aber das schöne, ich habe noch <a href="http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html" rel="nofollow">dieses Tutorial</a> gefunden und da wird explizit darauf hingewiesen, dass in <strong>C++</strong>, der Syntax von <code>foo</code> anders aussehen soll, also passe ich entsprechend an:</p>
<pre><code class="language-cpp">void foo(void* arg) {
...

pthread_create( &amp;threads[i], NULL, (void*)&amp;foo, (void *)&amp;data );
...
</code></pre>
<p>Dafür kriege ich jetzt die Fehlermeldung</p>
<pre><code>warning: ISO C++ forbids casting between pointer-to-function and pointer-to-object [enabled by default]
error: invalid conversion from ‘void*’ to ‘void* (*)(void*)’ [-fpermissive]
</code></pre>
<p>So, und wenn ich danach suche, dann kriege ich irgendwie alles mögliche an 'richtig' und 'falsch'.</p>
<p>Kann mir bitte jemand erklären was genau das Problem ist?</p>
<p>Viele Grüße,<br />
Klaus.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/332906/for-loop-und-pthread</link><generator>RSS for Node</generator><lastBuildDate>Mon, 27 Apr 2026 10:41:47 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/332906.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 29 May 2015 20:05:50 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to For loop und pthread on Fri, 29 May 2015 20:05:50 GMT]]></title><description><![CDATA[<p>Hallo ihr Lieben,</p>
<p>nach langer Zeit habe ich auch mal wieder eine Frage:</p>
<p>Ich versuche mich gerade am Parallelisieren mittels pthread und möchte dabei direkt ein paar Argumente übergeben.</p>
<p>Hier der Quellcode:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;pthread.h&gt;
#include &lt;string&gt;
#include &lt;vector&gt;

struct DATA {

  DATA(
	  const std::string&amp; s,
		const unsigned int&amp; i):
      dummy( s ), id(i) {};

	const std::string dummy;
	const unsigned int id;
};

void* foo(void* arg) {

	DATA* data = static_cast&lt;DATA*&gt;(arg);

	std::cout &lt;&lt; &quot;Thread Nr. &quot; &lt;&lt; data -&gt; id 
		        &lt;&lt; &quot; gives &quot; &lt;&lt; data -&gt; dummy &lt;&lt; std::endl;

  pthread_exit(NULL);
}

int main() {

  std::vector&lt;std::string&gt; dummies = { &quot;some&quot;,&quot;stuff&quot;,&quot;in&quot;,&quot;here&quot; };

	pthread_t threads[ dummies.size() ];

	for( unsigned int i = 0; i &lt; dummies.size(); ++i ) {

    DATA data( dummies[ i ], i );

    pthread_create( &amp;threads[i], NULL, foo, (void *)&amp;data );
  }

  pthread_exit(NULL);

	return 0;
}
</code></pre>
<p>Der Knackpunkt ist, dass die Ausgabe dabei Müll ist, z.B.</p>
<pre><code>Thread Nr. Thread Nr. 33 gives  gives herehere
3read Nr. Thread Nr. 3 gives hereH,D\�`�&lt;� �&lt;��`��� ����`{&lt;� {&lt;��`k�� k��!�f�f�&lt;�s��f�f�&lt;�s�
</code></pre>
<p>Dabei habe ich mich an <a href="http://www.tutorialspoint.com/cplusplus/cpp_multithreading.htm" rel="nofollow">diesem Beispiel</a> orientiert.</p>
<p>Jetzt kommt aber das schöne, ich habe noch <a href="http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html" rel="nofollow">dieses Tutorial</a> gefunden und da wird explizit darauf hingewiesen, dass in <strong>C++</strong>, der Syntax von <code>foo</code> anders aussehen soll, also passe ich entsprechend an:</p>
<pre><code class="language-cpp">void foo(void* arg) {
...

pthread_create( &amp;threads[i], NULL, (void*)&amp;foo, (void *)&amp;data );
...
</code></pre>
<p>Dafür kriege ich jetzt die Fehlermeldung</p>
<pre><code>warning: ISO C++ forbids casting between pointer-to-function and pointer-to-object [enabled by default]
error: invalid conversion from ‘void*’ to ‘void* (*)(void*)’ [-fpermissive]
</code></pre>
<p>So, und wenn ich danach suche, dann kriege ich irgendwie alles mögliche an 'richtig' und 'falsch'.</p>
<p>Kann mir bitte jemand erklären was genau das Problem ist?</p>
<p>Viele Grüße,<br />
Klaus.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2455166</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2455166</guid><dc:creator><![CDATA[Klaus82]]></dc:creator><pubDate>Fri, 29 May 2015 20:05:50 GMT</pubDate></item><item><title><![CDATA[Reply to For loop und pthread on Fri, 29 May 2015 21:05:25 GMT]]></title><description><![CDATA[<p>Hi!</p>
<p>Ohne mich zu sehr mit dem Code befasst zu haben, zwei Anmerkungen zu deinem Code:</p>
<p>1. Die Textausgabe via <code>cout</code> im Thread-Code ist nicht synchronisiert. Es ist daher je nach Implementation völlig normal, dass die Ausgabe verschiedener Threads ineinander verschachtelt ist. Um das zu vermeiden, solltest du vielleicht das <code>cout</code> mit einem Mutex schützen, so dass immer nur ein Thread eine &quot;Zeile&quot; text ausgeben kann.</p>
<p>2. Beim Erstellen des Threads in Zeile 38 übergibst du einen Pointer auf <code>data</code> , bei dem es sich jedoch um eine lokale Variable handelt, die höchstens bis zum abschließenden &quot; <code>}</code> &quot; der Schleife lebt. Die Threads geben daher Daten nicht mehr existierender Objekte aus. Ich vermute, dass bei jedem Schleifendurchlauf derselbe (Stack-) Speicherbereich verwendet wird, um die <code>DATA</code> -Instanz zu erzeugen, daher geben auch alle Threads die Nummer 3 aus - wobei es Zufall ist, dass das überhaupt halbwegs funktioniert, da wie gesagt, die übergebenen DATA-Objekte nichtmehr existieren, wenn <code>foo()</code> im anderen Thread zur Ausführung kommt.</p>
<p>Gruss,<br />
Finnegan</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2455168</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2455168</guid><dc:creator><![CDATA[Finnegan]]></dc:creator><pubDate>Fri, 29 May 2015 21:05:25 GMT</pubDate></item><item><title><![CDATA[Reply to For loop und pthread on Fri, 29 May 2015 21:10:15 GMT]]></title><description><![CDATA[<p>Hallo Finnega,</p>
<p>Finnegan schrieb:</p>
<blockquote>
<p>Hi!<br />
1. Die Textausgabe via <code>cout</code> im Thread-Code ist nicht synchronisiert.</p>
</blockquote>
<p>Ja, no problem with that so far! <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="🙂"
    /></p>
<p>Finnegan schrieb:</p>
<blockquote>
<p>2. Beim Erstellen des Threads in Zeile 38 übergibst du einen Pointer auf <code>data</code> , bei dem es sich jedoch um eine lokale Variable handelt, die höchstens bis zum abschließenden &quot; <code>}</code> &quot; der Schleife lebt. Die Threads geben daher Daten nicht mehr existierender Objekte aus. Ich vermute, dass bei jedem Schleifendurchlauf derselbe (Stack-) Speicherbereich verwendet wird, um die <code>DATA</code> -Instanz zu erzeugen, daher geben auch alle Threads die Nummer 3 aus - wobei es Zufall ist, dass das überhaupt halbwegs funktioniert, da wie gesagt, die übergebenen DATA-Objekte nichtmehr existieren, wenn <code>foo()</code> im anderen Thread zur Ausführung kommt.</p>
</blockquote>
<p>Daran bastle ich auch gerade herum. Ich habe jetzt vorher einen Vektor erzeugt, der alle relevanten <code>DATA</code> erhält und in dem <code>for-loop</code> dann mittels des Laufindex darauf zugegriffen wird.</p>
<p>Ich probier mich also weiter ... <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="🙂"
    /></p>
<p>Gruß,<br />
Klaus.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2455169</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2455169</guid><dc:creator><![CDATA[Klaus82]]></dc:creator><pubDate>Fri, 29 May 2015 21:10:15 GMT</pubDate></item><item><title><![CDATA[Reply to For loop und pthread on Fri, 29 May 2015 21:44:54 GMT]]></title><description><![CDATA[<p>Klaus82 schrieb:</p>
<blockquote>
<p>Daran bastle ich auch gerade herum. Ich habe jetzt vorher einen Vektor erzeugt, der alle relevanten <code>DATA</code> erhält und in dem <code>for-loop</code> dann mittels des Laufindex darauf zugegriffen wird.</p>
</blockquote>
<p>Ich habe selbst auch schon öfter mit solchen C-Interfaces zu tun gehabt, denen man User-Daten nur über einen <code>void*</code> übergeben konnte, und bei denen die benötigte Lebensdauer der Objekte nicht genau vorherbestimmbar war (asynchrone Verarbeitung in anderen Threads), und auch noch mehrere Threads auf die selben Objekte zugreifen mussten. In diesem Fall hat sich oft ein <code>std::shared_ptr</code> bewährt, den ich - was einem auf den ersten Blick die Haare zu Berge stehen lassen sollte - via <code>new</code> erzeugt habe:</p>
<pre><code>auto object = std::make_shared&lt;Object&gt;();
   ...
   std::shared_ptr&lt;Object&gt;* userData = new std::shared_ptr&lt;Object&gt;(object);
   asynchrones_c_interface(userData);
</code></pre>
<p>... das allerdings nur um den <code>shared_ptr</code> durch das C-Interface zu &quot;tunneln&quot;. In der Thread-Funktion (bei der garantiert sein sollte, dass diese auch ausgeführt wird, sonst leckt es) wurde dieser dann direkt gelöscht, um möglichst wenig mit nackten, &quot;owning&quot; Pointern herumhantieren zu müssen:</p>
<pre><code>void thread_function(void* userData)
   {
      auto objectPtr = static_cast&lt;std::shared_ptr&lt;Object&gt;*&gt;(userData);
      std::shared_ptr&lt;Object&gt; object = *objectPtr;
      delete objectPtr;
      ...
      // mach was mit object.
   }
</code></pre>
<p>Vielleicht ist ja ein ähnliches Pattern auch für dein Program nützlich.<br />
Ansonsten empfiehlt sich vielleicht auch eher, <code>std::thread</code> zu benutzen, falls du darauf Zugriff hast, dort kann man dann die <code>shared_ptr</code> direkt an die Thread-Funktion übergeben ohne dieses etwas seltsame <code>shared_ptr</code> -Pointer-Gedöns <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
<p>Gruss,<br />
Finnegan</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2455170</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2455170</guid><dc:creator><![CDATA[Finnegan]]></dc:creator><pubDate>Fri, 29 May 2015 21:44:54 GMT</pubDate></item><item><title><![CDATA[Reply to For loop und pthread on Fri, 29 May 2015 21:55:01 GMT]]></title><description><![CDATA[<p>Finnegan schrieb:</p>
<blockquote>
<pre><code>void thread_function(void* userData)
   {
      auto objectPtr = static_cast&lt;std::shared_ptr&lt;Object&gt;*&gt;(userData);
      std::shared_ptr&lt;Object&gt; object = *objectPtr;
      delete objectPtr;
      ...
      // mach was mit object.
   }
</code></pre>
</blockquote>
<p>Vielleicht gibt es Fälle, wo man einen shared_ptr braucht, aber der default sollte unique_ptr sein.</p>
<pre><code class="language-cpp">auto object = std::make_unique&lt;Object&gt;();
asynchrones_c_interface(object.release());

void thread_function(void* userData) {
    auto object = unique_ptr&lt;Object&gt;(static_cast&lt;Object*&gt;(userData));
    // mach was mit object.
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2455171</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2455171</guid><dc:creator><![CDATA[thin and gone]]></dc:creator><pubDate>Fri, 29 May 2015 21:55:01 GMT</pubDate></item><item><title><![CDATA[Reply to For loop und pthread on Fri, 29 May 2015 22:24:08 GMT]]></title><description><![CDATA[<p>Benutze std::thread oder boost::thread!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2455174</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2455174</guid><dc:creator><![CDATA[manni66]]></dc:creator><pubDate>Fri, 29 May 2015 22:24:08 GMT</pubDate></item></channel></rss>