Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mutex lock threads

Am new to multi threaded/processs programming. So here's what I need to clarify.

Process A code

pthread_mutex_lock()     pthread_create(fooAPI(sharedResource)) //fooAPI creates another thread with shared resource that shares across processes. pthread_mutex_unlock() 

With the above pseudo code, is process B able to access sharedResource if mutex is not unlocked?

How can I access the sharedResource from process B correctly?

Any there any clear visual diagram that explains the relationship between mutexes, threads and processes?

like image 519
resting Avatar asked Feb 15 '13 03:02

resting


People also ask

Can multiple threads lock on a mutex?

The non-member function lock allows to lock more than one mutex object simultaneously, avoiding the potential deadlocks that can happen when multiple threads lock/unlock individual mutex objects in different orders.

What is difference between mutex and lock?

A lock allows only one thread to enter the part that's locked and the lock is not shared with any other processes. A mutex is the same as a lock but it can be system wide (shared by multiple processes).

What is mutex threading?

A mutual exclusion (mutex) is used cooperatively between threads to ensure that only one of the cooperating threads is allowed to access the data or run certain application code at a time. The word mutex is shorthand for a primitive object that provides MUTual EXclusion between threads.

How does mutex know to lock?

Mutex only locks a thread. It does not lock a resource. You can still access it via direct memory manipulation. So in that sense it is not safe (but on the other hand nothing can stop you from direct memory manipulation).


1 Answers

What you need to do is to call pthread_mutex_lock to secure a mutex, like this:

pthread_mutex_lock(&mutex); 

Once you do this, any other calls to pthread_mutex_lock(mutex) will not return until you call pthread_mutex_unlock in this thread. So if you try to call pthread_create, you will be able to create a new thread, and that thread will be able to (incorrectly) use the shared resource. You should call pthread_mutex_lock from within your fooAPI function, and that will cause the function to wait until the shared resource is available.

So you would have something like this:

#include <pthread.h> #include <stdio.h>  int sharedResource = 0; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;  void* fooAPI(void* param) {     pthread_mutex_lock(&mutex);     printf("Changing the shared resource now.\n");     sharedResource = 42;     pthread_mutex_unlock(&mutex);     return 0; }  int main() {     pthread_t thread;      // Really not locking for any reason other than to make the point.     pthread_mutex_lock(&mutex);     pthread_create(&thread, NULL, fooAPI, NULL);     sleep(1);     pthread_mutex_unlock(&mutex);      // Now we need to lock to use the shared resource.     pthread_mutex_lock(&mutex);     printf("%d\n", sharedResource);     pthread_mutex_unlock(&mutex); } 

Edit: Using resources across processes follows this same basic approach, but you need to map the memory into your other process. Here's an example using shmem:

#include <stdio.h> #include <unistd.h> #include <sys/file.h> #include <sys/mman.h> #include <sys/wait.h>  struct shared {     pthread_mutex_t mutex;     int sharedResource; };  int main() {     int fd = shm_open("/foo", O_CREAT | O_TRUNC | O_RDWR, 0600);     ftruncate(fd, sizeof(struct shared));      struct shared *p = (struct shared*)mmap(0, sizeof(struct shared),         PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);      p->sharedResource = 0;      // Make sure it can be shared across processes     pthread_mutexattr_t shared;     pthread_mutexattr_init(&shared);     pthread_mutexattr_setpshared(&shared, PTHREAD_PROCESS_SHARED);      pthread_mutex_init(&(p->mutex), &shared);      int i;     for (i = 0; i < 100; i++) {         pthread_mutex_lock(&(p->mutex));         printf("%d\n", p->sharedResource);         pthread_mutex_unlock(&(p->mutex));         sleep(1);     }      munmap(p, sizeof(struct shared*));     shm_unlink("/foo"); } 

Writing the program to make changes to p->sharedResource is left as an exercise for the reader. :-)

Forgot to note, by the way, that the mutex has to have the PTHREAD_PROCESS_SHARED attribute set, so that pthreads will work across processes.

like image 106
Brian Avatar answered Sep 18 '22 23:09

Brian