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?
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.
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).
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.
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).
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With