Chinaunix首页 | 论坛 | 博客
  • 博客访问: 204149
  • 博文数量: 24
  • 博客积分: 608
  • 博客等级: 中士
  • 技术积分: 371
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-22 21:10
文章分类

全部博文(24)

文章存档

2012年(24)

分类: LINUX

2012-09-26 14:09:33

编写一个程序,开启3个线程,这3个线程的ID分别为ABC,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC.依次递推。

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <pthread.h>
  4. #include <unistd.h>
  5. #include <string.h>
  6. #define DEBUG 1
  7.   
  8. int num = 0;
  9. pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;
  10. pthread_cond_t qready=PTHREAD_COND_INITIALIZER;

  11. void* thread_func(void *arg)
  12. {
  13.     int param = (int) arg;
  14.     int i;
  15.     
  16.     for(i = 0; i < 10; i++)
  17.     {
  18.         pthread_mutex_lock(&mylock);
  19.         
  20.         while(param != num)
  21.             pthread_cond_wait(&qready, &mylock);
  22.         
  23.         printf("%c", param + 'A');
  24.         num = (num + 1) % 3;
  25.         
  26.         pthread_mutex_unlock(&mylock);
  27.         pthread_cond_broadcast(&qready);
  28.     }
  29.     
  30.     return (void *)0;
  31. }

  32. int main()
  33. {
  34.     int i;
  35.     pthread_t tid[3];
  36.     void *tret;
  37.     
  38.     for(i = 0; i < 3; i++)
  39.         pthread_create(&tid[i], NULL, thread_func, (void *) i);
  40.     for(i = 0; i < 3; i++)
  41.         pthread_join(tid[i], &tret);    
  42. }
首先开辟3个子线程,分别为a,b,c,其中a负责打印'A', b负责打印'B',c负责打印'C'。然后abc开始执行,首先a,b,c都去尝试加锁,其中有一个加锁成功,另外两个则阻塞等待在那里。不妨假设b加锁成功(其实这个可以控制放a先加锁成功);这时a和c线程都阻塞等待加锁,b线程开始执行,当执行到while(param != num),因为他的param是1所以!= num(0),所以他会执行下面的条件变量等待语句,于是他暂时释放当前锁,然后等待在条件变量qread之上。因为此时b释放了锁,那么a和c线程就有机会进入循环了。可以发现如果c获得了锁他的状态和b一样都是阻塞在条件变量之上。于是条件变量就有了一个队列:
c b
这时a就可以执行下面的语句了因为在a线程不执行条件变量等待,然后打印出'A',把num置为1,以此可以让b线程执行。然后a线程释放锁,唤醒所有阻塞在条件变量里面的线程(pthread_cond_broadcast(&qready);),然后b和c就都唤醒了。于是再一次去抢占加锁,不妨假设c抢到了锁,然后他再一次被伤害了,因为他需要执行while语句里面的条件变量等待,此时的条件变量将阻塞a和c线程,于是c再一次被阻塞,理所当然的b执行了线程打印出了‘B',后面的故事就一样了。
如此便可以有效的控制线程的输出顺序!

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