linux同步机制之互斥锁
版权声明:如有需要,可供转载,但请注明出处:https://blog.csdn.net/City_of_skey/article/details/85494572 目录1、简介2、API2.1 pthread_mutex_init2.2 pthread_mutex_lock2.3 pthread_mutex_trylock2.4 pthread_mutex_tim...
版权声明:如有需要,可供转载,但请注明出处:https://blog.csdn.net/City_of_skey/article/details/85494572
目录
1、简介
linux多线程的环境中为了保证变量的同步需要使用互斥锁mutex,当一个线程使用互斥锁时,另一个线程就会阻塞进入睡眠状态。互斥锁本质上是信号量的一个特例,信号量是可以多个线程共享资源,而互斥锁同时只能一个进程使用资源。互斥锁不能使用在中断因为中断不能休眠。互斥锁也不能递归
2、API
2.1 pthread_mutex_init
互斥锁的初始化有两种:动态初始化、静态初始化,动态初始化调用pthread_mutex_init,一般默认是缺省模式所以,第二个参数是NULL,
pthread_mutex_init(&lock, NULL)
静态初始化是调用宏 PTHREAD_MUTEX_INITIALIZER
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER
2.2 pthread_mutex_lock
这个函数就会加锁,如果已经被锁住那么线程就会阻塞进入休眠,如果加锁成功那么其他进程就不能就会进入阻塞休眠状态。
2.3 pthread_mutex_trylock
这个函数在Pthread_mutex_lock的基础上做了改进,调用该函数如果没有获取锁就会返回EBUSY错误码,表示该锁已经被其他线程占用,立即返回而不是进入阻塞状态。
2.4 pthread_mutex_timedlock
pthread_mutex_timedlock是在pthread_mutex_lock的基础上添加了超时时间,如果超过了这个时间还没有获取锁就返回,返回错误码ETIMEDOUT,第二个参数是超时时间变量struct timespec abs_timeout。
struct timespec abs_timeout;
abs_timeout.tv_sec = time(NULL) + 1;
abs_timeout.tv_nsec = 0;
3.5 pthread_mutex_unlock
释放锁
2.6 pthread_mutex_destroy
销毁互斥锁,释放空间。
3、例子
不加互斥锁:
#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
#include<stdlib.h>
int g_val = 0;
void *fun1(void *argv){
int i = 0;
for(i = 0; i < 10000; ++i){
g_val += 1;
}
}
int main(){
pthread_t t1, t2;
pthread_create(&t1, NULL, fun1, NULL);
pthread_create(&t2, NULL, fun1, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
printf("g_val:%d\n", g_val);
}
运行结果:
root@ubuntu:/home/c_test/mutex# ./a.out
g_val:20000
root@ubuntu:/home/c_test/mutex# ./a.out
g_val:19839
root@ubuntu:/home/c_test/mutex# ./a.out
g_val:11580
root@ubuntu:/home/c_test/mutex# ./a.out
g_val:20000
root@ubuntu:/home/c_test/mutex# ./a.out
g_val:20000
因为两个线程同时对全局变量g_val做加的操作而没有加锁,最终g_val的值是不确定的。
加互斥锁:
#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
#include<stdlib.h>
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
int g_val = 0;
void *fun1(void *argv){
int i = 0;
for(i = 0; i < 10000; ++i){
pthread_mutex_lock(&lock);
g_val += 1;
pthread_mutex_unlock(&lock);
}
}
int main(){
pthread_t t1, t2;
pthread_create(&t1, NULL, fun1, NULL);
pthread_create(&t2, NULL, fun1, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
pthread_mutex_destroy(&lock);
printf("g_val:%d\n", g_val);
}
运行结果:
root@ubuntu:/home/c_test/mutex# ./a.out
g_val:20000
root@ubuntu:/home/c_test/mutex# ./a.out
g_val:20000
root@ubuntu:/home/c_test/mutex# ./a.out
g_val:20000
root@ubuntu:/home/c_test/mutex# ./a.out
g_val:20000
root@ubuntu:/home/c_test/mutex# ./a.out
g_val:20000
加了互斥锁后每次运行结果都是20000.
4、比较
1、当没有获取锁时互斥锁就会阻塞进入休眠状态,但自旋锁不会休眠会一致在等待,如果资源锁定时间短用自旋锁的效率更高,内核开发中使用自旋锁比较多,但如果资源锁定时间长建议使用互斥锁。自旋锁不会休眠如果资源要休眠建议使用互斥锁、信号量。
2、互斥锁和信号量先比互斥锁占用空间比信号量小,效率比信号量高。
更多推荐
所有评论(0)