Chinaunix首页 | 论坛 | 博客
  • 博客访问: 7723869
  • 博文数量: 961
  • 博客积分: 15795
  • 博客等级: 上将
  • 技术积分: 16612
  • 用 户 组: 普通用户
  • 注册时间: 2010-08-07 14:23
文章分类

全部博文(961)

文章存档

2016年(1)

2015年(61)

2014年(41)

2013年(51)

2012年(235)

2011年(391)

2010年(181)

分类: LINUX

2011-06-18 23:32:30

  1. /*
  2.  * Produce/Consume using multithread
  3.  */

  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <pthread.h>
  7. #include <string.h>
  8. #include <assert.h>
  9. #include <time.h>
  10. #include <unistd.h>
  11. #include <errno.h>

  12. #define BSIZE    30        //buffer size
  13. #define PRODUCE_EXIT    '~'    //produce thread exit flag
  14. #define CONSUME_EXIT    '@'    //consume thread exit flag
  15. #define PRODUCE_NUMBER    3    //produce thread number
  16. #define CONSUME_NUMBER    5    //consume thread number

  17. typedef struct buffer_t
  18. {
  19.     char            buf[BSIZE];
  20.     int                occupied;    //product number
  21.     int                nextin;
  22.     int                nextout;
  23.     pthread_mutex_t    mutex;
  24.     pthread_cond_t    less;
  25.     pthread_cond_t    more;
  26. }buffer_t;

  27. pthread_once_t once = PTHREAD_ONCE_INIT;

  28. buffer_t ware;

  29. /*
  30.  * initialization
  31.  */
  32. void init(void)
  33. {
  34.     memset(&ware, 0, sizeof(ware));
  35.     pthread_mutex_init(&ware.mutex, NULL);
  36.     pthread_cond_init(&ware.less, NULL);
  37.     pthread_cond_init(&ware.more, NULL);
  38. }
  39. /*
  40.  * destroy
  41.  */
  42. void destroy(void)
  43. {
  44.     pthread_mutex_destroy(&ware.mutex);
  45.     pthread_cond_destroy(&ware.less);
  46.     pthread_cond_destroy(&ware.more);
  47. }

  48. /*
  49.  * The produce thread
  50.  */
  51. void * threadProduce(void * arg)
  52. {
  53.     char c = 0;
  54.     struct timespec tt;
  55.     int result;
  56.     
  57.     while(c != PRODUCE_EXIT)
  58.     {
  59.         //read product from keyboard
  60.         c = getchar();
  61.         if(c == '\n')
  62.             continue;
  63.         
  64.         //lock mutex
  65.         assert( pthread_mutex_lock(&ware.mutex) == 0);
  66.         //condition wait
  67.         tt.tv_sec = time(NULL)+1;
  68.         tt.tv_nsec= 0;
  69.         if(ware.occupied >= BSIZE)
  70.         {
  71.             result = pthread_cond_timedwait(
  72.                         &ware.more,
  73.                         &ware.mutex,
  74.                         &tt);
  75.             if(result == ETIMEDOUT)
  76.             {
  77.                 assert( pthread_mutex_unlock(&ware.mutex) == 0);
  78.                 continue;
  79.             }else if(result != 0)
  80.             {
  81.                 printf("pthread_cond_timedwait ERROR.\n");
  82.                 assert( pthread_mutex_unlock(&ware.mutex) == 0);
  83.                 pthread_exit(NULL);
  84.             }
  85.         }
  86.         //insert product into buf
  87.         ware.buf[ware.nextin] = c;
  88.         ware.occupied++;
  89.         ware.nextin = (ware.nextin+1)%BSIZE;

  90.         printf("produce: [tid=%u] [%c].\n",
  91.                 pthread_self(), c);
  92.         
  93.         //aware the consume thread
  94.         pthread_cond_signal(&ware.less);
  95.         //unlock mutex
  96.         assert( pthread_mutex_unlock(&ware.mutex) == 0);
  97.         sleep(1);
  98.     }
  99.     printf("produce [tid=%u] EXIT.\n", pthread_self());
  100.     pthread_exit(NULL);
  101. }

  102. /*
  103.  * The consume thread
  104.  */
  105. void * threadConsume(void * arg)
  106. {
  107.     char c = 0;
  108.     struct timespec tt;
  109.     int result;
  110.     
  111.     while(c != CONSUME_EXIT)
  112.     {
  113.         //lock mutex
  114.         assert( pthread_mutex_lock(&ware.mutex) == 0);
  115.         //condition wait
  116.         tt.tv_sec = time(NULL)+1;
  117.         tt.tv_nsec= 0;
  118.         if(ware.occupied <= 0)
  119.         {
  120.             result = pthread_cond_timedwait(
  121.                         &ware.less,
  122.                         &ware.mutex,
  123.                         &tt);
  124.             if(result == ETIMEDOUT)
  125.             {
  126.                 assert( pthread_mutex_unlock(&ware.mutex) == 0);
  127.                 continue;
  128.             }else if(result != 0)
  129.             {
  130.                 printf("pthread_cond_timedwait ERROR.\n");
  131.                 assert( pthread_mutex_unlock(&ware.mutex) == 0);
  132.                 pthread_exit(NULL);
  133.             }
  134.         }
  135.         //read product from buf
  136.         c = ware.buf[ware.nextout];
  137.         ware.occupied--;
  138.         ware.nextout = (ware.nextout+1)%BSIZE;
  139.         printf("consume: [tid=%u] [%c].\n",
  140.                 pthread_self(), c);
  141.         
  142.         //aware the produce thread
  143.         pthread_cond_signal(&ware.more);
  144.         //unlock mutex
  145.         assert( pthread_mutex_unlock(&ware.mutex) == 0);
  146.         sleep(1);
  147.     }
  148.     printf("consume [tid=%u] EXIT.\n", pthread_self());
  149.     pthread_exit(NULL);
  150. }
  151.                         
  152. int main(void)
  153. {
  154.     pthread_t tid[PRODUCE_NUMBER+CONSUME_NUMBER];
  155.     int i;
  156.     
  157.     pthread_once(&once, init);
  158.     for(i=0; i<PRODUCE_NUMBER; i++)
  159.     {
  160.         if( pthread_create(&tid[i], NULL,
  161.                     threadProduce, NULL) )
  162.         {
  163.             printf("pthread_create ERROR.\n");
  164.             destroy();
  165.             exit(-1);
  166.         }
  167.     }
  168.     for(; i<PRODUCE_NUMBER+CONSUME_NUMBER; i++)
  169.     {
  170.         if( pthread_create(&tid[i], NULL,
  171.                     threadConsume, NULL) )
  172.         {
  173.             printf("pthread_create ERROR.\n");
  174.             destroy();
  175.             exit(-1);
  176.         }
  177.     }
  178.     
  179.     for(i=0; i<PRODUCE_NUMBER+CONSUME_NUMBER; i++)
  180.     {
  181.         pthread_join(tid[i], NULL);
  182.     }
  183.     destroy();
  184.     
  185.     pthread_exit(NULL);
  186. }
  1. /*
  2.  * 线程同步
  3.  */
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <pthread.h>
  7. #include <assert.h>

  8. int product = 0;

  9. pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
  10. pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;

  11. /*
  12.  * 线程函数 读
  13.  */
  14. void * threadRead(void * arg)
  15. {
  16.     int cnt = 0;
  17.     while(cnt++ < 100)
  18.     {
  19. //        assert( pthread_mutex_lock(&mutex) == 0);
  20.         assert( pthread_rwlock_rdlock(&rwlock) == 0);
  21.         
  22.         printf("Read: product = %d\n", product);
  23.         
  24. //        assert( pthread_mutex_unlock(&mutex) == 0);
  25.         assert( pthread_rwlock_unlock(&rwlock) == 0);
  26.         sleep(1);
  27.     }
  28.     pthread_exit(NULL);
  29. }

  30. /*
  31.  * 线程函数 写 增加
  32.  */
  33. void * threadProduce(void * arg)
  34. {
  35.     int cnt = 0;
  36.     while(cnt++ < 100)
  37.     {
  38. //        assert( pthread_mutex_lock(&mutex) == 0);
  39.         assert( pthread_rwlock_wrlock(&rwlock) == 0);
  40.         
  41.         product++;
  42.         printf("Produce: product = %d\n", product);
  43.         
  44. //        assert( pthread_mutex_unlock(&mutex) == 0);
  45.         assert( pthread_rwlock_unlock(&rwlock) == 0);
  46.         sleep(2);
  47.     }
  48.     pthread_exit(NULL);
  49. }

  50. /*
  51.  * 线程函数 写 减少
  52.  */
  53. void * threadConsume(void * arg)
  54. {
  55.     int cnt = 0;
  56.     while(cnt++ < 100)
  57.     {
  58. //        assert( pthread_mutex_lock(&mutex) == 0);
  59.         assert( pthread_rwlock_wrlock(&rwlock) == 0);
  60.         
  61.         product--;
  62.         printf("Consume: product = %d\n", product);
  63.         
  64. //        assert( pthread_mutex_unlock(&mutex) == 0);
  65.         assert( pthread_rwlock_unlock(&rwlock) == 0);
  66.         sleep(2);
  67.     }
  68.     pthread_exit(NULL);
  69. }    

  70. int main(void)
  71. {
  72.     pthread_t tidRead[20], tidProduce, tidConsume;
  73.     int i;
  74.     
  75.     for(i=0; i<20; i++)
  76.         if( pthread_create(&tidRead[i], NULL,
  77.                         threadRead, NULL) )
  78.         {
  79.             printf("pthread_create ERROR\n");
  80.             exit(-1);
  81.         }
  82.     
  83.     if( pthread_create(&tidProduce, NULL,
  84.                     threadProduce, NULL) )
  85.     {
  86.         printf("pthread_create ERROR\n");
  87.         exit(-1);
  88.     }
  89.     
  90.     if( pthread_create(&tidConsume, NULL,
  91.                     threadConsume, NULL) )
  92.     {
  93.         printf("pthread_create ERROR\n");
  94.         exit(-1);
  95.     }
  96.     
  97.     pthread_exit(NULL);
  98. }
阅读(1978) | 评论(0) | 转发(2) |
给主人留下些什么吧!~~