千家信息网

unix 线程同步之 条件变量 及 互斥锁 测试例子

发表于:2025-02-23 作者:千家信息网编辑
千家信息网最后更新 2025年02月23日,#include #include #include #include #include #include #include # define satisfy true# define u
千家信息网最后更新 2025年02月23日unix 线程同步之 条件变量 及 互斥锁 测试例子
  1. #include <pthread.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <sys/time.h>
  5. #include <stdbool.h>
  6. #include <errno.h>
  7. #include <unistd.h>
  8. # define satisfy true
  9. # define unsatisfy false
  10. //pthread_mutex_t mut_loc = PTHREAD_MUTEX_INITIALIZER;//所为静态初始化为PTHREAD_MUTEX_INITIALIZER为一个常量,在全局中进行赋值
  11. pthread_mutex_t mut_loc;
  12. pthread_cond_t thd_con;
  13. struct timespec tsp;
  14. bool condition = unsatisfy;
  15. void maketimeout(struct timespec *tsp, int add_sec)//设置超时函数,当前的时间再加上需要等待时候,因为pthread_cond_timedwait只认识当前时间格式
  16. {
  17. struct timeval now;
  18. gettimeofday(&now,NULL);//获取当前时间
  19. tsp->tv_sec = now.tv_sec;
  20. tsp->tv_nsec = now.tv_usec *1000;
  21. tsp->tv_sec += add_sec; //等待20秒
  22. }
  23. void thread0(void)
  24. {
  25. int ret;
  26. if(0 != pthread_mutex_lock(&mut_loc))//上锁
  27. {
  28. perror("pthread_mutex_lock_0\n");
  29. return;
  30. }
  31. if(condition == unsatisfy)
  32. {
  33. fputs("条件不满足,重新等待条件!!\n",stdout);
  34. maketimeout(&tsp, 2);//设置超时时间2秒
  35. //等待条件,并且解锁,线程转到等待队列中,如果条件满足信号收到,即会进行上锁;
  36. //线程是处于一种叫做无竞争方式,由于条件未满足情况下不会与其它线程竞争锁,只有条件满足后才会进行竞争
  37. ret = pthread_cond_timedwait(&thd_con,&mut_loc,&tsp);
  38. if(ETIMEDOUT == ret)
  39. {
  40. fputs("直到超时条件都不满足,重新等待条件!!\n",stdout);
  41. }
  42. else if(0 == ret)
  43. {
  44. fputs("线程0在等待时候获得条件满足!\n",stdout);
  45. }
  46. else
  47. {
  48. perror("other error for pthread_cond_timedwait \n");
  49. pthread_exit((void *)1);
  50. }
  51. if(condition == satisfy)
  52. {
  53. fputs("0_条件满足!!\n",stdout);
  54. condition = unsatisfy;
  55. }
  56. }
  57. else if(condition == satisfy)
  58. {
  59. fputs("1_条件满足!!\n",stdout);
  60. condition = unsatisfy;
  61. }
  62. else
  63. {
  64. perror("error condition\n ");
  65. pthread_exit((void *)1);
  66. }
  67. if(0 != pthread_mutex_unlock(&mut_loc))
  68. {
  69. perror("pthread_mutex_lock_0\n");
  70. return;
  71. }
  72. pthread_exit((void *)0);
  73. }
  74. void thread1(void)
  75. {
  76. int ret;
  77. ret = pthread_mutex_trylock(&mut_loc);
  78. if(EBUSY == ret)
  79. {
  80. fputs("锁被线程0所占有!\n",stdout);
  81. }
  82. else if(0 == ret)
  83. {
  84. if(0 != pthread_cond_signal(&thd_con))
  85. {
  86. perror("pthread_cond_signal\n");
  87. pthread_exit((void *)1);
  88. }
  89. condition = satisfy;
  90. fputs("线程1使条件满足\n",stdout);
  91. if(0 != pthread_mutex_unlock(&mut_loc))
  92. {
  93. perror("pthread_mutex_lock_1\n");
  94. pthread_exit((void *)1);
  95. }
  96. }
  97. else
  98. {
  99. perror("other errors for pthread_mutex_lock_1\n");
  100. pthread_exit((void *)1);
  101. }
  102. pthread_exit((void *)0);
  103. }
  104. int main(int argc, char* argv[])
  105. {
  106. pthread_t thd0, thd1;
  107. if(0 != pthread_mutex_init(&mut_loc,NULL))// pthread_mutex_init 与 pthread_mutex_destroy配对使用,因为其是动态即使用malloc来产生
  108. {
  109. perror("pthread_mutex_init\n");
  110. exit(1);
  111. }
  112. if(0 != pthread_cond_init(&thd_con,NULL))// pthread_cond_init 与 pthread_cond_destroy配对使用,因为其是动态即使用malloc来产生
  113. {
  114. perror("pthread_cond_init\n");
  115. exit(1);
  116. }
  117. if(0 != pthread_create(&thd0,NULL,(void*)thread0,NULL))//创建线程0
  118. {
  119. perror("pthread_create_0\n");
  120. exit(1);
  121. }
  122. sleep(1);//让线程0先执行
  123. if(0 != pthread_create(&thd1,NULL,(void*)thread1,NULL))//创建线程1
  124. {
  125. perror("pthread_create_0\n");
  126. exit(1);
  127. }
  128. if(0 != pthread_join(thd1,NULL))//如果线程牌分离属性此函数不可用,如果线程1不退出,则处于阻塞状态
  129. {
  130. perror("pthread_join_0\n");
  131. exit(1);
  132. }
  133. if(0 != pthread_join(thd0,NULL))//如果线程牌分离属性此函数不可用,如果线程0不退出,则处于阻塞状态
  134. {
  135. perror("pthread_join_1\n");
  136. exit(1);
  137. }
  138. if(0 != pthread_cond_destroy(&thd_con))//与pthread_cond_init配对使用
  139. {
  140. perror("pthread_cond_destory\n");
  141. exit(1);
  142. }
  143. if(0 != pthread_mutex_destroy(&mut_loc))//与pthread_mutex_init配对使用
  144. {
  145. perror("pthread_mutex_init\n");
  146. exit(1);
  147. }
  148. return 0;
  149. }
0