Note that there are some explanatory texts on larger screens.

plurals
  1. POWhat is the difference between passing a loop counter or range-declaration to a thread by reference?
    primarykey
    data
    text
    <pre><code>#include &lt;iostream&gt; #include &lt;memory&gt; #include &lt;vector&gt; #include "boost/thread.hpp" using boost::thread; using std::vector; using std::unique_ptr; class ThreadPool { public: ThreadPool(int size) : max_size_(size) {} ~ThreadPool() { Join(); } void PollForSpace() { while (static_cast&lt;int&gt;(pool_.size()) &gt;= max_size_) { for (auto it = pool_.begin(); it != pool_.end(); ++it) { if ((*it)-&gt;timed_join(boost::posix_time::milliseconds(10))) { pool_.erase(it); break; } } } } void AddToPool(unique_ptr&lt;thread&gt; t) { pool_.push_back(std::move(t)); } void Join() { for (auto it = pool_.begin(); it != pool_.end(); ++it) { (*it)-&gt;join(); } pool_.clear(); } protected: vector&lt;unique_ptr&lt;thread&gt; &gt; pool_; int max_size_; }; int main(int argc, char** argv) { ThreadPool pool(20); std::vector&lt;int&gt; integers; for (int i = 0; i &lt; 100; ++i) { integers.push_back(i); } std::cout &lt;&lt; "Range based for loop over vector." &lt;&lt; std::endl; for (auto const&amp; i : integers) { pool.PollForSpace(); pool.AddToPool(unique_ptr&lt;thread&gt;(new thread([&amp;i]{ std::cout &lt;&lt; i &lt;&lt; std::endl; }))); } pool.Join(); std::cout &lt;&lt; "Integer loop." &lt;&lt; std::endl; for (int i = 0; i &lt; 100; ++i) { pool.PollForSpace(); pool.AddToPool(unique_ptr&lt;thread&gt;(new thread([&amp;i]{ std::cout &lt;&lt; i &lt;&lt; std::endl; }))); } pool.Join(); return 0; } </code></pre> <p>Why does the range-based for-loop properly print out the numbers 0-99 (although not necessarily in order, and with occasionally newlines interspersed incorrectly), but the integer loop causes print out like this:</p> <pre><code>1 2 3 4 5 6 7 8 9 13 1414 14 14 15 16 18 18 19 ... 99 100 </code></pre> <p>As I understand it, the integer is being passed by reference to the thread, but its value is changed in the main loop before the thread gets to print it out, causing some values to be not printed out, some values to be printed out more than once, and the value 100 to be printed, even though <code>i</code> obtains that value after the last thread is created.</p> <p>However, I don't see why this is also not an issue when using the range-based for-loop.</p> <p>Why does the range-based for-loop version not suffer from the same concurrency issues as the plain integer loop in this code?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload