A mutex is basically a lock that we set(lock) before accessing a shared resource and release(unlock) when we're done. While it is set, any other thread tries to set it will block until we release it.
system call definition:
ubuntu@ip-172-31-23-227:~$ less /usr/include/pthread.h
......
/* Initialize a mutex. */
extern int pthread_mutex_init (pthread_mutex_t *__mutex,
const pthread_mutexattr_t *__mutexattr)
__THROW __nonnull ((1));
/* Destroy a mutex. */
extern int pthread_mutex_destroy (pthread_mutex_t *__mutex)
__THROW __nonnull ((1));
/* Try locking a mutex. */
extern int pthread_mutex_trylock (pthread_mutex_t *__mutex)
__THROWNL __nonnull ((1));
/* Lock a mutex. */
extern int pthread_mutex_lock (pthread_mutex_t *__mutex)
__THROWNL __nonnull ((1));
/* Unlock a mutex. */
extern int pthread_mutex_unlock (pthread_mutex_t *__mutex)
__THROWNL __nonnull ((1));
......
Before using a mutex, we need to either initialize it to PTHREAD_MUTEX_INITIALIZER or call pthread_mutex_init.
If we allocate the mutex dynamically, when we need to call pthread_mutex_destroy before freeing the memory.
pthread_mutex_trylock behaves conditionally:
1) if mutex is locked, it will return EBUSY without blocking, without locking the mutex.
2) if mutex is not locked, it will lock the mutex without blocking.
2. Example:
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
int value = 0;
pthread_mutex_t lock;
void* thr_fn1(void *arg)
{
pthread_mutex_trylock(&lock);
printf("thread 1 trylocked\n");
value++;
sleep(3);
printf("thread 1 unlocked\n");
pthread_mutex_unlock(&lock);
}
int main(int argc, char* argv[])
{
// Initialize mutex
if(pthread_mutex_init(&lock, NULL) != 0) {
printf("mutex init failed.\n");
exit(1);
}
// launch the thread 1
pthread_t tid1;
if(pthread_create(&tid1, NULL, thr_fn1, NULL) != 0) {
printf("pthread_create failed.\n");
exit(2);
}
// main thread sleep 2 seconds to let thread 1 run firstly
sleep(2);
printf("waiting for thread 1 lock...\n");
pthread_mutex_lock(&lock);
printf("main thread locked\n");
value++;
pthread_mutex_unlock(&lock);
printf("value = %d\n", value);
exit(0);
}
shell:
Firstly, main thread fell asleep to let thread 1 run firstly. Thread 1 "trylock" the mutex, and sleep 3 seconds. During this period, main thread waked up and and lock the mutex, but at this time, thread 1 still doesn't release the lock.
After 1 second, thread 1 wake up and release the lock. Main thread acquire the lock.
ubuntu@ip-172-31-23-227:~$ ./trylock.out
thread 1 trylocked
waiting for thread 1 lock...
thread 1 unlocked
main thread locked
value = 2
===============================================================
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
int value = 0;
pthread_mutex_t lock;
void* thr_fn1(void *arg)
{
if(pthread_mutex_trylock(&lock) == 0) {
printf("thread 1 trylocked\n");
value++;
printf("thread 1 unlocked\n");
pthread_mutex_unlock(&lock);
}
else {
printf("thread trylock failed, but it doesn't block!\n");
}
}
int main(int argc, char* argv[])
{
// Initialize mutex
if(pthread_mutex_init(&lock, NULL) != 0) {
printf("mutex init failed.\n");
exit(1);
}
// Main thread lock the mutex
pthread_mutex_lock(&lock);
printf("main thread locked\n");
value++;
// launch the thread 1
pthread_t tid1;
if(pthread_create(&tid1, NULL, thr_fn1, NULL) != 0) {
printf("pthread_create failed.\n");
exit(2);
}
// Sleep 2 seconds to let thread 1 execute
sleep(2);
pthread_mutex_unlock(&lock);
printf("value = %d\n", value);
exit(0);
}
shell:
Firstly, main thread lock the mutex. And then launch the thread 1, who will trylock the mutex, but at this time, mutex is already locked by main thread, so trylock failed, but it doesn't block there, it keep executing and output:
"thread trylock failed, but it doesn't block!". Then thread 1 is finished.
After 2 seconds, main thread wake up and release the mutex.
ubuntu@ip-172-31-23-227:~$ ./trylock.out
main thread locked
thread trylock failed, but it doesn't block!
value = 1
No comments:
Post a Comment