4343|0

241

帖子

4

TA的资源

纯净的硅(初级)

楼主
 

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.        
  15.         res = pthread_mutex_init(&work_mutex,NULL);
  16.         if(res != 0){
  17.                 perror("mutex initialization failed ...\n");
  18.                 exit(EXIT_FAILURE);
  19.         }
  20.        
  21.         res = pthread_create(&thread_id1,NULL,pthread1,NULL);
  22.         if(res != 0){
  23.                 perror("pthread1 is not created ...\n");
  24.                 exit(EXIT_FAILURE);
  25.         }

  26.         res = pthread_create(&thread_id2,NULL,pthread2,NULL);
  27.         if(res != 0){
  28.                 perror("pthread2 is not created ...\n");
  29.                 exit(EXIT_FAILURE);
  30.         }

  31.         res = pthread_join(thread_id1,&thread_result1);
  32.         if(res != 0){
  33.                 perror("pthread1 join failed ...\n");
  34.                 exit(EXIT_FAILURE);
  35.         }

  36.         res = pthread_join(thread_id2,&thread_result2);
  37.         if(res != 0){
  38.                 perror("pthread2 join failed ...\n");
  39.                 exit(EXIT_FAILURE);
  40.         }
  41.        
  42.         printf("the pthread1 return %s\n",(char *)thread_result1);
  43.         printf("the pthread2 return %s\n",(char *)thread_result2);
  44.        
  45.         pthread_mutex_destroy(&work_mutex);
  46.         return 0;
  47. }


  48. void *pthread1(void *arg)
  49. {
  50.         int i;
  51.         for(i=0;i<5;i++){
  52.                 pthread_mutex_lock(&work_mutex);
  53.                 printf("hello this is pthread1 --> %d\n",i);
  54.                 pthread_mutex_unlock(&work_mutex);
  55.                 sleep(2);
  56.         }
  57.         pthread_exit("pthread1 finished ...\n");       
  58. }

  59. void *pthread2(void *arg)
  60. {
  61.         int i;
  62.         for(i=0;i<5;i++){
  63.                 pthread_mutex_lock(&work_mutex);
  64.                 printf("hello this is pthread2 --> %d\n",i);
  65.                 pthread_mutex_unlock(&work_mutex);
  66.                 sleep(2);       
  67.         }
  68.         pthread_exit("pthread2 finished ...\n");
  69. }
复制代码

运行结果
  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

点赞 关注

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表