Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>There are several things going on here that are preventing you from seeing the context switching behavior you are expecting:</p> <ol> <li>The threads are basically sitting in tight loops. It's not very likely that a context switch will happen in the middle.</li> <li>You did have an odd context switch in your example when <code>w(2)</code> prints <code>6</code>, and then <code>47</code>. It switches from 3 to 2 and back again.</li> <li>The access to the global variable is probably being optimized away by the C++ compiler. Making the variable <code>volatile</code> could help. Note that <code>volatile</code> is not really a solution. For example, increments may not be an atomic operation (aka fetch, increment, store), and also CPU caches can sometimes cause weird artifacts because stores to memory are not seen by all CPUs at the time they're executed.</li> <li>You are not using <code>endl</code>. Normally, I think <code>endl</code> is an absolutely horrible idea. But in this case it means that all the writes are being buffered up, which may cause some interesting artifacts.</li> <li>Additionally, <code>cout</code> will be thread-safe and the locks required to make this happen may also affect the way the threads context switch with each other.</li> </ol> <p>A number of these problems can be solved by calling the <code>write</code> system call directly. This will force a system call which may give another thread the opportunity to run. It will also force the output to happen exactly when the code for it is executed.</p> <p>Here is a program that will exhibit the behavior you were looking for on a multi-core Unix box. It will also show you the final value of <code>k</code> to demonstrate why <code>volatile</code> isn't really much of a solution, and how it created a race on the value <code>k</code>. I originally just suggested it as a hack to make your program work slightly better for producing the behavior you were looking for because in your original program it didn't really matter:</p> <pre><code>#include &lt;boost/thread.hpp&gt; #include &lt;iostream&gt; #include &lt;unistd.h&gt; volatile int threads = 0; const int iterations = 200; volatile int k = 0; void w(char thid) { threads++; for (int i = 0; i &lt; iterations; i++) { k++; ::write(1, &amp;thid, 1); } } int main(int argc, char* argv[]) { boost::thread a(&amp;w, '0'); boost::thread b(&amp;w, '1'); boost::thread c(&amp;w, '2'); boost::thread d(&amp;w, '3'); a.join(); b.join(); c.join(); d.join(); ::write(1, "\n", 1); // In general, do not mix write to stdout and cout. In this case // it will work, but this is a very limited and specific case. ::std::cout &lt;&lt; "k == " &lt;&lt; k &lt;&lt; "\n"; return 0; } </code></pre>
    singulars
    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. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      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