Note that there are some explanatory texts on larger screens.

plurals
  1. POpthread mutex (un)locking over different threads
    primarykey
    data
    text
    <p>I have a process where main initializes a mutex calling:</p> <pre class="lang-c prettyprint-override"><code>MutexInit( pthread_mutex_t *Mutex ) { pthread_mutexattr_t mattr; pthread_mutexattr_init(&amp;mattr); pthread_mutexattr_settype(&amp;mattr, PTHREAD_MUTEX_ERRORCHECK_NP); #ifndef _POSIX_THREAD_PROCESS_SHARED #error "This platform does not support process shared mutex!" #else pthread_mutexattr_setpshared(&amp;mattr, PTHREAD_PROCESS_SHARED); #endif pthread_mutex_init( Mutex, &amp;mattr ); } </code></pre> <p><code>main</code> is initially locking mutex M1 and creates then threads T1 and T2.</p> <p>T1 is started and does some work. T2 is started and does something else and at some point doing a lock on that mutex M1. Since mutex type is PTHREAD_MUTEX_ERRORCHECK_NP T2 is not blocked, instead error EDEADLK is returned, indicating that the mutex M1 is already locked. So T2 continues trying to lock. That's fine so far.</p> <p>Then T1 comes to the point where it unlocks M1, but error EPERM is returned, saying, that T1 does not own the mutex !? So T2 never gets unlocked.</p> <p>If I remove setting the attributes from <code>MutexInit</code>:</p> <pre class="lang-c prettyprint-override"><code>pthread_mutexattr_init(&amp;mattr); pthread_mutexattr_settype(&amp;mattr, PTHREAD_MUTEX_ERRORCHECK_NP); #ifndef _POSIX_THREAD_PROCESS_SHARED #error "This platform does not support process shared mutex!" #else pthread_mutexattr_setpshared(&amp;mattr, PTHREAD_PROCESS_SHARED); #endif </code></pre> <p>and calling <code>pthread_mutex_init( Mutex, NULL );</code>, ie. default attributes, everything is working fine !</p> <p>I do need the initial <code>MutexInit</code> routine, because we're also using mutexes over processes (via shared memory).</p> <p>Does anybody have any idea ? I've read so many articles and posts, so any help will be appriciated.</p> <p><strong>EDIT</strong>: Using a modified version of Paolo's code to demonstrate my observation:</p> <p>This a the modified version of Paolo's code to fit "my sequencing":</p> <pre class="lang-c prettyprint-override"><code>#include &lt;stddef.h&gt; #include &lt;pthread.h&gt; #include &lt;stdio.h&gt; #include &lt;string.h&gt; #include &lt;semaphore.h&gt; pthread_mutex_t m; sem_t s1, s2; void print(const char *s, int err) { printf("%s %d %s\n", s, err, strerror(err)); } void *start_t1(void *arg) { sem_wait(&amp;s1); // &lt;-t2 print("t1: unlock ", pthread_mutex_unlock(&amp;m)); sem_post(&amp;s2); //-&gt;t2 } void *start_t2(void *arg) { sem_wait(&amp;s2); // &lt;-main print("t2: lock ", pthread_mutex_lock(&amp;m)); sem_post(&amp;s1); // -&gt;t1 sem_wait(&amp;s2); // &lt;-t1 sem_post(&amp;s1); // -&gt;main } void main(void) { pthread_mutexattr_t mattr; pthread_mutexattr_init(&amp;mattr); pthread_mutexattr_settype(&amp;mattr, PTHREAD_MUTEX_ERRORCHECK_NP); pthread_mutexattr_setpshared(&amp;mattr, PTHREAD_PROCESS_SHARED); sem_init(&amp;s1, 0, 0); sem_init(&amp;s2, 0, 0); print("main init", pthread_mutex_init(&amp;m, &amp;mattr)); pthread_t t2, t1; pthread_create(&amp;t1, NULL, start_t1, NULL); pthread_create(&amp;t2, NULL, start_t2, NULL); sem_post(&amp;s2); // -&gt;t2 sem_wait(&amp;s1); // &lt;-t2 pthread_join(t1, NULL); pthread_join(t2, NULL); } </code></pre> <p>The output is:</p> <pre><code>main init 0 Success t2: lock 0 Success t1: unlock 1 Operation not permitted </code></pre> <p>I would expect T1 to be allowed to unlock the mutex because of type <code>PTHREAD_PROCESS_SHARED</code>. Am I wrong ?</p> <p>If the mutex initialization is changed to defaults (<code>pthread_mutex_init(&amp;m, **NULL**)</code>), then it's working.</p> <pre><code>main init 0 Success t2: lock 0 Success t1: unlock 0 Success </code></pre> <p>Seems to be some kind of inverted logic !</p>
    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