Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4241923
  • 博文数量: 1148
  • 博客积分: 25453
  • 博客等级: 上将
  • 技术积分: 11949
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-06 21:14
文章分类

全部博文(1148)

文章存档

2012年(15)

2011年(1078)

2010年(58)

分类: C/C++

2011-05-16 10:36:45

互斥锁原理:
         互斥锁防止共享数据被并发修改,全局变量属于共享数据。
         如果互斥锁处于锁定状态,默认阻塞等待

基本操作函数

  1. 初始化:      pthread_mutex_init
  2. 申请 :       pthread_mutex_lock
  3. 释放 :        pthread_mutex_unlock
  4. 非阻塞申请:   pthread_mutex_trylock
  5. 销毁 :       pthrea_mutex_destroy

下面的实例:
    主线程负责从 stdin 输入数据到全局数据区,work_area[],子线程负责将读入的数据输出到标准输出设备。
    1. 在输入数据时,需要占有全局数据区 work_area[], 首先上锁,在输入数据完毕后,解锁
    2. 在输出数据时,需要占有全局数据区 work_area[],  首先上锁,后解锁

使用互斥锁,很好的解决了两个线程之间的同步机制


  1. #include <stdio.h>
  2. #include <pthread.h>
  3. #include <stdlib.h>
  4. #include <unistd.h>
  5. #include <semaphore.h>
  6. #include <string.h>

  7. void *thread_fun(void *a);  //子线程函数
  8. void print_res(int *res,char *s); //判断 成功
  9. pthread_mutex_t work_mutex; //全局互斥锁对象
  10.          /* typedef struct
  11.              {
  12.                 int volatile value;    到磁盘上数据读入,不再内存中
  13.              }pthread_mutex_t*/

  14. #define WORK_SIZE 1024
  15. char work_area[WORK_SIZE]; //全局共享数据区

  16. int time_to_exit = 0; //全局数据
  17.                        //互斥锁:防止对共享数据(全局变量) 并发修改

  18. int main(int argc, char *argv[])
  19. {
  20.     int res;
  21.     pthread_t a_thread; //unsigned long
  22.     void *thread_result;    //thread_join() 的第二个参数
  23.     
  24.     //初始化 互斥锁 NULL 默认属性
  25.     res = pthread_mutex_init(&work_mutex, NULL);
  26.     print_res(&res, "pthread_mutex_init");

  27.     //创建新线程
  28.     res = pthread_create(&a_thread, NULL, thread_fun, NULL);
  29.     print_res(&res, "pthread_create");

  30.     //接受输入前,给互斥锁上锁                //假设,子线程先执行,但是在子线程中 sleep(1);
  31.     pthread_mutex_lock(&work_mutex);       //所以,还是主线程 mutex_lock 先获得 锁,
  32.                                            //所以,还是 主线程,执行 输入数据 先
  33.     printf("input some text.enter 'end' to finish\n");

  34.     while(!time_to_exit) //time_to_exit 由另一个线程修改  //初始值 0
  35.     {
  36.         fgets(work_area, WORK_SIZE, stdin); //冲stdin 读取一行信息
  37.         pthread_mutex_unlock(&work_mutex);//解锁,两个线程抢占互斥锁
  38.         
  39.         while(1)
  40.         {
  41.             pthread_mutex_lock(&work_mutex); //上锁
  42.             if(work_area[0] != '\0')//检查读入的内容输出没有
  43.             { //输出线程将信息输出后设置为 work_area[0] = '\0'
  44.                 pthread_mutex_unlock(&work_mutex);
  45.                 sleep(1);
  46.             }    
  47.             else //如果已经输出,执行下一轮读入
  48.             {
  49.                 break;
  50.             }
  51.         }
  52.     }

  53.     //解锁
  54.     pthread_mutex_unlock(&work_mutex); //解锁
  55.     printf("\nwaiting for thread to finish...\n");

  56.     //等待退出线程
  57.     res =pthread_join(a_thread, (void **)&thread_result);
  58.     print_res(&res, "pthread_join");

  59.     //销毁互斥锁
  60.     pthread_mutex_destroy(&work_mutex);
  61.     
  62.     exit(EXIT_SUCCESS);
  63. }

  64. void print_res(int *res,char *s)
  65. {
  66.     if(*res != 0)
  67.     {
  68.         printf("%s failed.\n",s);
  69.         exit(EXIT_FAILURE);
  70.     }
  71.     else
  72.     {
  73.         printf("%s success\n",s);
  74.     }
  75. }

  76. void *thread_fun(void *a)
  77. {
  78.     sleep(1); //假如,子线程先执行,那么等待 1 秒,可以使主线程
  79.                   //首先抢到 锁,进行输入数据

  80.     //上锁,抢占资源
  81.     pthread_mutex_lock(&work_mutex);

  82.     while(strncmp("end",work_area,3) != 0) //判断是否为结束信息 end
  83.     {
  84.         printf("you input %d characters\n",strlen(work_area)-1); //输出输入的字符数
  85.         printf("the characters is:%s",work_area);
  86.         work_area[0]='\0'; //输出输入的字符后,设置 输出标志
  87.         
  88.         pthread_mutex_unlock(&work_mutex); //解锁
  89.         
  90.         sleep(1);//等待 主线程抢占锁 ,可以输入数据

  91.         pthread_mutex_lock(&work_mutex);
  92.         
  93.         while(work_area[0] =='\0') //判断第一位 是否为 0
  94.         {        // = 0 ,主线程没有输入 数据
  95.                                 //= 0 ,有输入,执行下一轮输出操作
  96.             pthread_mutex_unlock(&work_mutex);
  97.             sleep(1); //使主线程,进行输入数据
  98.             pthread_mutex_lock(&work_mutex); //上锁,再次返回判断
  99.         }
  100.     }
  101.     
  102.     time_to_exit = 1;
  103.     work_area[0] = '\0';
  104.     pthread_mutex_unlock(&work_mutex);
  105.     
  106.     pthread_exit(0);
  107. }

  1. ywx@yuweixian:~/yu/professional/4$ ./mutex
  2. pthread_mutex_init success
  3. pthread_create success
  4. input some text.enter 'end' to finish
  5. love linux
  6. you input 10 characters
  7. the characters is:love linux
  8. ssssss
  9. you input 6 characters
  10. the characters is:ssssss
  11. end

  12. waiting for thread to finish...
  13. pthread_join success


阅读(5441) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~