Note that there are some explanatory texts on larger screens.

plurals
  1. PODead lock without a explicit lock
    primarykey
    data
    text
    <p>I am testing a pthread program.</p> <p>This program is simple. The main thread creates a child thread. </p> <p>The main thread and the child thread are both operating on a queue.</p> <p>The child thread keeps scanning the queue and return the minimal element and its position with a infinite loop.</p> <p>The main thread also is running a loop, each iteration of which delete the minimal element calculated by the child thread from the queue, and insert some new elements to the end of the queue.</p> <p>The minimal element and its position, and the queue are all declared as global variables.</p> <p>The main ends when the queue is empty and it will cancel the child thread.</p> <p>This progress is some like a breadth-first search.</p> <p>The queue is implemented as an array with a size counter. The deletion operation is implemented as replacing the element to be deleted by the last element and decreasing the size counter by one.</p> <p>No lock is used here. But when running, the program will get stuck.</p> <p>What's more amazing, if I insert some printf statements to view the status, it may finish.</p> <p><strong>I want to know what causes this program endless?</strong></p> <pre><code>struct multiblocks_pthread_args { volatile int local_e; volatile int local_v; volatile int local_pos; int* Q; int* val; volatile int* size; } para; volatile int update = 0; void* child_thread ( void* args ) { pthread_setcanceltype ( PTHREAD_CANCEL_ASYNCHRONOUS, NULL ); multiblocks_pthread_args* arglist = ( multiblocks_pthread_args* ) args; bindToCore ( 1 ); int* list = arglist -&gt; Q, * value = arglist -&gt; val; while ( true ) { int size, e, v, pos; do { size = * ( arglist-&gt;size ), e, v = INF, pos = 0; update = 0; for ( int i = 0; i &lt; size; i++ ) { int vi = value[i]; if ( vi &lt; v ) { pos = i; v = vi; } } } while ( update ); if ( size &gt; 0 ) e = list[pos]; arglist-&gt;local_e = e; arglist-&gt;local_pos = pos; arglist-&gt;local_v = v; } return NULL; } void main_thread () { int size; int* Q = ( int* ) malloc ( sizeof ( int ) * NumNode ); int** hash = ( int** ) malloc ( sizeof ( int* ) * numNode ); NodeColor* color = ( NodeColor* ) malloc ( sizeof ( NodeColor ) * numNode ); // NodeColor is a enum with 3 values: WHITE, GRAY, BLACK memset ( color, 0, sizeof ( NodeColor ) * numNode ); pthread_t tid; para.val = ( int* ) malloc ( sizeof ( int ) * NumNode ); para.Q = Q; para.size = &amp;size; pthread_create ( &amp;tid, NULL, child_thread, &amp;para ); // Only one element is in the queue size = 0; para.Q[size] = 0; para.val[size] = 0; hash[0] = &amp;para.val[size]; // hash is used to modify the value of particular element ++size; color[0] = GRAY; while ( true ) { int global_e, global_v = INF, global_pos; global_e = para.local_e, global_v = para.local_v, global_pos = para.local_pos; if ( size == 0 ) break; if ( color[global_e] != BLACK ) { value[global_e] = global_v, color[global_e] = BLACK; if ( size &gt; 0 ) { --size; para.Q[global_pos] = para.Q[size]; para.val[global_pos] = para.val[size]; hash[para.Q[global_pos]] = &amp; para.val[global_pos]; update = 1; } for ( int i = 0; i &lt; MAXDEG; ++i ) { int ee = ;// new element; int vv = ;// value of new element; if ( /* if new element is valid */ ) { if ( color[ee] == WHITE ) { // WHITE means ee is not in the queue para.Q[size] = ee; para.val[size] = vv; hash[ee] = &amp;para.val[size]; ++size, color[ee] = GRAY; } else { *hash[ee] = vv; } update = 1; } } } } free ( Q ); pthread_cancel ( tid ); printf ( "Computation finishes!!!" ); return ; } </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.
 

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