mutex在Linux中称为互斥量,由mutex实现的锁叫做互斥锁。Java中对于重量级锁(关键字10)的实现就是mutex。

mutex为什么叫做重量级锁?

因为互斥的特点是拿不到锁就sleep,调用sleep()会进入到内核态,发生了一次系统调用。

pthread_mutex 定义

image.png

pthread_mutex_lock 定义

image.png :::tips int pthread_mutex_init(pthread_mutex_t mutex, const pthread_mutexattr_t attr); :::

使用mutex

mutextest.c

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <pthread.h>
  4. int sharei = 0; //定义一个全局变量
  5. void increase_num(void);
  6. // add mutex
  7. pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;//PTHREAD_MUTEX_INITIALIZER是一个宏,会去调用OS的pthread_mutex_init函数
  8. int main()
  9. {
  10. int ret;
  11. pthread_t thread1,thread2,thread3;
  12. ret = pthread_create(&thread1,NULL,(void *)&increase_num,NULL);
  13. ret = pthread_create(&thread2,NULL,(void *)&increase_num,NULL);
  14. ret = pthread_create(&thread3,NULL,(void *)&increase_num,NULL);
  15. //pthread_join 防止主线程直接结束
  16. pthread_join(thread1,NULL);
  17. pthread_join(thread2,NULL);
  18. pthread_join(thread3,NULL);
  19. printf("sharei = %d\n",sharei);
  20. return 0;
  21. }
  22. //run
  23. void increase_num(void)
  24. {
  25. long i,tmp;
  26. for(i =0;i<=9999;++i)
  27. {
  28. //上锁
  29. pthread_mutex_lock(&mutex);
  30. //有同学问为什么不加锁会小于30000
  31. //比如当t1 执行到tmp=sharei的时候假设 sharei这个时候=0,那么tmp也等于0
  32. //然后tmp=tmp+1;结果tmp=1(t1);这个时候如果t2进入了
  33. //t2获取的sharei=0;然后重复t1的动作 tmp=1(t2)
  34. //t2 sharei = tmp; sharei = 1;
  35. //然后CPU切回t1 执行 sharei = tmp; sharei = 1;
  36. //结果两个线程执行了两遍但是结果还是sharei = 1;(本来要等于2的)
  37. tmp=sharei;
  38. tmp=tmp+1;
  39. sharei = tmp;
  40. //解锁
  41. pthread_mutex_unlock(&mutex);
  42. }
  43. }

编译mutextest.c

gcc mutextest.c -o mu -pthread

注释掉加锁的代码

会发现得到的结果小于30000
image.png

放开加锁的代码

image.png