Note that there are some explanatory texts on larger screens.

plurals
  1. POThread synchronization issue: possible race, misuse of volatile, cache coherency?
    primarykey
    data
    text
    <p>I am getting acquainted with <strong>pthreads</strong> programming; the following code is a simple producer/consumer design where data is put/fetched from a global list. The problem is: the data pointer in the consumer function is tried to be freed twice. Beside, if I add a <code>printf()</code> at the beginning of the loop, everything seems ok... What am I doing wrong? I suspect a misuse of the <code>volatile</code> keyword, or something hidden by the cache... Unless it's just a design issue (which probably is :p).</p> <p>Thanks for your insights.</p> <p>Note: <code>malloc()/free()</code> is thread-safe on my system. I am compiling with <code>$ gcc -pthread -O0</code> which should, I guess, reduce possible design errors due to misuse of <code>volatile</code>. Finally, we don't care in this code snippet with running out of memory (in case of more producer than consumer).</p> <p><strong>Edit:</strong> Changed code to a single list head.</p> <pre><code>#include &lt;pthread.h&gt; #include &lt;stdlib.h&gt; #include &lt;string.h&gt; pthread_mutex_t lock; pthread_cond_t new_data; struct data { int i; struct data *next; }; struct data *list_head = NULL; void *consume(void *arg) { struct data *data; while (1) { pthread_mutex_lock(&amp;lock); while (list_head == NULL) { pthread_cond_wait(&amp;new_data, &amp;lock); } data = list_head; list_head = list_head-&gt;next; pthread_mutex_unlock(&amp;lock); free(data); } return NULL; } void *produce(void *arg) { struct data *data; while (1) { data = malloc(sizeof(struct data)); pthread_mutex_lock(&amp;lock); data-&gt;next = list_head; list_head = data; pthread_mutex_unlock(&amp;lock); pthread_cond_signal(&amp;new_data); } return NULL; } int main() { pthread_t tid[2]; int i; pthread_mutex_init(&amp;lock, NULL); pthread_cond_init(&amp;new_data, NULL); pthread_create(&amp;tid[0], NULL, consume, NULL); pthread_create(&amp;tid[1], NULL, produce, NULL); for (i = 0; i &lt; 2; i++) { pthread_join(tid[i], NULL); } } </code></pre> <p>And the output:</p> <pre><code>$ ./a.out *** glibc detected *** ./a.out: double free or corruption (fasttop): 0x00007f5870109000 *** </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.
 

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