[原创] Helper2416-45——Linux_Programing——POSIX线程同步篇2

yuanlai2010   2014-9-12 13:07 楼主
POSIX线程同步篇2
用互斥量进行同步
参与Helper2416开发板助学计划心得
什么是互斥量(互斥锁)
如果不需要信号量的计数能力,有时可以使用信号量的一个简化版本,称为互斥量(mutex)。互斥量仅仅适用于管理共享资源或一小段代码。由于互斥量在实现时既容易又有效,这使得互斥量在实现用户空间线程包时非常有用。
互斥量是一个可以处于两态之一的变量:解锁和加锁。这样,只需要一个二进制位表示它,不过实际上,常常使用一个整型量,0表示解锁,而其他所有的值则表示加锁。互斥量使用两个过程。当一个线程(或进程)需要访问临界区时,它调用pthread_mutex_lock。如果该互斥量当前是解锁的(即临界区可用),此调用成功,调用线程可以自由进入该临界区。
另一方面,如果该互斥量已经加锁,调用线程被阻塞,直到在临界区中的线程完成并调用pthread_mutex_unlock。如果多个线程被阻塞在该互斥量上,将随机选择一个线程并允许它获得锁。
pthread互斥量函数
用于互斥量的基本函数和用于信号量的函数非常相似,定义如下:
#include
intpthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t*mutexattr);
intpthread_mutex_lock(pthread_mutex_t *mutex);
intpthread_mutex_unlock(pthread_mutex_t *mutex);
intpthread_mutex_destroy(pthread_mutex_t *mutex);
pthread_mutex_init
函数原型:intpthread_mutex_init(pthread_mutex_t *mutex,
constpthread_mutexattr_t *mutexattr);
函数功能:初始化互斥量。
函数返回:调用成功返回0
参数说明:
第一个参数mutex,指定互斥量对象。
第二个参数mutexattr指定了新建互斥量的属性。如果参数attr为空,则使用默认的互斥锁属性,默认属性为快速互斥量。但是通常并不需要这些属性,所以正常做法是指定NULL
thread_mutex_lock
函数原型:intpthread_mutex_lock(pthread_mutex_t *mutex);
函数功能:锁定互斥对象。
函数返回:调用成功返回0
参数说明:mutex,接受一个指向互斥对象的指针作为参数以将其锁定。如果碰巧已经锁定了互斥对象,调用者将进入睡眠状态。函数返回时,将唤醒调用者(显然)并且调用者还将保留该锁。
pthread_mutex_unlock
函数原型:intpthread_mutex_unlock(pthread_mutex_t *mutex);
函数功能:把线程已经加锁的互斥对象解锁。
函数返回:调用成功返回0
参数说明:mutex,指定互斥量对象。始终应该尽快对已加锁的互斥对象进行解锁(以提高性能)。并且绝对不要对您未保持锁的互斥对象进行解锁操作(否则,pthread_mutex_unlock()调用将失败并带一个非零的EPERM返回值)。
pthread_mutex_destroy
函数原型:intpthread_mutex_destroy(pthread_mutex_t *mutex);
函数功能:用完互斥量后对它进行清理。
函数返回:调用成功返回0
参数说明:mutex,指向要销毁的互斥锁对象。
代码实践
  1. #include <pthread.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <unistd.h>
  5. void *pthread1(void *arg);
  6. void *pthread2(void *arg);
  7. pthread_mutex_t work_mutex;
  8. int run_flag = 0;
  9. int main()
  10. {
  11. pthread_t thread_id1,thread_id2;
  12. void *thread_result1, *thread_result2;
  13. int res;
  14. res = pthread_mutex_init(&work_mutex,NULL);
  15. if(res != 0){
  16. perror("mutex initialization failed ...\n");
  17. exit(EXIT_FAILURE);
  18. }
  19. res = pthread_create(&thread_id1,NULL,pthread1,NULL);
  20. if(res != 0){
  21. perror("pthread1 is not created ...\n");
  22. exit(EXIT_FAILURE);
  23. }
  24. res = pthread_create(&thread_id2,NULL,pthread2,NULL);
  25. if(res != 0){
  26. perror("pthread2 is not created ...\n");
  27. exit(EXIT_FAILURE);
  28. }
  29. res = pthread_join(thread_id1,&thread_result1);
  30. if(res != 0){
  31. perror("pthread1 join failed ...\n");
  32. exit(EXIT_FAILURE);
  33. }
  34. res = pthread_join(thread_id2,&thread_result2);
  35. if(res != 0){
  36. perror("pthread2 join failed ...\n");
  37. exit(EXIT_FAILURE);
  38. }
  39. printf("the pthread1 return %s\n",(char *)thread_result1);
  40. printf("the pthread2 return %s\n",(char *)thread_result2);
  41. pthread_mutex_destroy(&work_mutex);
  42. return 0;
  43. }
  44. void *pthread1(void *arg)
  45. {
  46. int i;
  47. for(i=0;i<5;i++){
  48. pthread_mutex_lock(&work_mutex);
  49. printf("hello this is pthread1 --> %d\n",i);
  50. pthread_mutex_unlock(&work_mutex);
  51. sleep(2);
  52. }
  53. pthread_exit("pthread1 finished ...\n");
  54. }
  55. void *pthread2(void *arg)
  56. {
  57. int i;
  58. for(i=0;i<5;i++){
  59. pthread_mutex_lock(&work_mutex);
  60. printf("hello this is pthread2 --> %d\n",i);
  61. pthread_mutex_unlock(&work_mutex);
  62. sleep(2);
  63. }
  64. pthread_exit("pthread2 finished ...\n");
  65. }
运行结果
  1. [yuanlai@fedora pthread]$ ./pthread2
  2. hello this is pthread2 --> 0
  3. hello this is pthread1 --> 0
  4. hello this is pthread2 --> 1
  5. hello this is pthread1 --> 1
  6. hello this is pthread2 --> 2
  7. hello this is pthread1 --> 2
  8. hello this is pthread2 --> 3
  9. hello this is pthread1 --> 3
  10. hello this is pthread2 --> 4
  11. hello this is pthread1 --> 4
  12. the pthread1 return pthread1 finished ...
  13. the pthread2 return pthread2 finished ...
  14. [yuanlai@fedora pthread]$
得到的实验现象与使用信号量的结果时一样的,暂时还没能找到好些的方式来体现出互斥量的特性,初学理解的还不够透彻,这里只是简单记录该怎么使用互斥量。
二值信号量与互斥量的区别
互斥量必须是在同一个任务申请,同一个任务释放,其他任务释放无效。
二值信号量,一个任务申请后,可以由其他任务释放。
论坛IDyuanlai2010
发表时间:2014-09-12
本帖最后由 yuanlai2010 于 2014-9-12 13:07 编辑

回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复