multithreading - pthread mutex (un)locking over different threads -
i have process main initializes mutex calling:
mutexinit( pthread_mutex_t *mutex ) { pthread_mutexattr_t mattr; pthread_mutexattr_init(&mattr); pthread_mutexattr_settype(&mattr, pthread_mutex_errorcheck_np); #ifndef _posix_thread_process_shared #error "this platform not support process shared mutex!" #else pthread_mutexattr_setpshared(&mattr, pthread_process_shared); #endif pthread_mutex_init( mutex, &mattr ); }
main
locking mutex m1 , creates threads t1 , t2.
t1 started , work. t2 started , else , @ point doing lock on mutex m1. since mutex type pthread_mutex_errorcheck_np t2 not blocked, instead error edeadlk returned, indicating mutex m1 locked. t2 continues trying lock. that's fine far.
then t1 comes point unlocks m1, error eperm returned, saying, t1 not own mutex !? t2 never gets unlocked.
if remove setting attributes mutexinit
:
pthread_mutexattr_init(&mattr); pthread_mutexattr_settype(&mattr, pthread_mutex_errorcheck_np); #ifndef _posix_thread_process_shared #error "this platform not support process shared mutex!" #else pthread_mutexattr_setpshared(&mattr, pthread_process_shared); #endif
and calling pthread_mutex_init( mutex, null );
, ie. default attributes, working fine !
i need initial mutexinit
routine, because we're using mutexes on processes (via shared memory).
does have idea ? i've read many articles , posts, appriciated.
edit: using modified version of paolo's code demonstrate observation:
this modified version of paolo's code fit "my sequencing":
#include <stddef.h> #include <pthread.h> #include <stdio.h> #include <string.h> #include <semaphore.h> 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(&s1); // <-t2 print("t1: unlock ", pthread_mutex_unlock(&m)); sem_post(&s2); //->t2 } void *start_t2(void *arg) { sem_wait(&s2); // <-main print("t2: lock ", pthread_mutex_lock(&m)); sem_post(&s1); // ->t1 sem_wait(&s2); // <-t1 sem_post(&s1); // ->main } void main(void) { pthread_mutexattr_t mattr; pthread_mutexattr_init(&mattr); pthread_mutexattr_settype(&mattr, pthread_mutex_errorcheck_np); pthread_mutexattr_setpshared(&mattr, pthread_process_shared); sem_init(&s1, 0, 0); sem_init(&s2, 0, 0); print("main init", pthread_mutex_init(&m, &mattr)); pthread_t t2, t1; pthread_create(&t1, null, start_t1, null); pthread_create(&t2, null, start_t2, null); sem_post(&s2); // ->t2 sem_wait(&s1); // <-t2 pthread_join(t1, null); pthread_join(t2, null); }
the output is:
main init 0 success t2: lock 0 success t1: unlock 1 operation not permitted
i expect t1 allowed unlock mutex because of type pthread_process_shared
. wrong ?
if mutex initialization changed defaults (pthread_mutex_init(&m, **null**)
), it's working.
main init 0 success t2: lock 0 success t1: unlock 0 success
seems kind of inverted logic !
this not see... notice eperm t2 should return, not t1. , dually, edeadlk t1 should return if lock same mutex twice recursively.
this code used test:
#include <stddef.h> #include <pthread.h> #include <stdio.h> #include <string.h> #include <semaphore.h> 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_t2(void *arg) { print("t2", pthread_mutex_unlock(&m)); sem_post(&s1); sem_wait(&s2); } void main(void) { pthread_mutexattr_t mattr; pthread_mutexattr_init(&mattr); pthread_mutexattr_settype(&mattr, pthread_mutex_errorcheck_np); pthread_mutexattr_setpshared(&mattr, pthread_process_shared); pthread_mutex_init(&m, &mattr); sem_init(&s1, 0, 0); sem_init(&s2, 0, 0); print("t1", pthread_mutex_lock(&m)); pthread_t t2; pthread_create(&t2, null, start_t2, null); sem_wait(&s1); print("t1", pthread_mutex_unlock(&m)); sem_post(&s2); pthread_join(t2, null); }
Comments
Post a Comment