免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3773 | 回复: 7
打印 上一主题 下一主题

[C] 多线程问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-11-05 16:35 |只看该作者 |倒序浏览
本帖最后由 youzlm 于 2010-11-05 16:37 编辑

需求:
一个队列,刚开始为空
一些线程给队列填数据。
别一些线程读队列数据。
问题:
我想专门开几个线程来等待队列不是空时就取出来显示。
要如何监听这个队列,来唤醒线程读取数据

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
2 [报告]
发表于 2010-11-05 16:39 |只看该作者
条件变量

论坛徽章:
0
3 [报告]
发表于 2010-11-05 16:41 |只看该作者
semphore

论坛徽章:
0
4 [报告]
发表于 2010-11-05 16:47 |只看该作者
读线程:pthread_cond_wait
写线程:pthread_cond_broadcast

论坛徽章:
0
5 [报告]
发表于 2010-11-05 17:30 |只看该作者
读线程一个,写进程多个

那是不是每写一个数据都要唤醒读线程吗?

论坛徽章:
0
6 [报告]
发表于 2010-11-06 15:12 |只看该作者
在读的线程放一个pthread_cond_wait,
在写线程上放pthread_cond_broadcast,
当读线程上有数据就入进队更,唤醒写线程。
这样变成了,队列没有用,一次只处理一个数据

如何改一下。。就是写线程一有数据就写进队列。
读线程只要队列有数据就读数据

论坛徽章:
0
7 [报告]
发表于 2010-11-06 22:00 |只看该作者
不知道是不是你的需求。

  1. /********************************************************************
  2. created:        2009/10/08
  3. modify :    2009/10/08
  4. file :         TQueue.h
  5. author:               
  6. purpose:    Thread Safe FIFO queue
  7. *********************************************************************/

  8. #ifndef TQUEUE_H_
  9. #define TQUEUE_H_

  10. #include "apr_thread_mutex.h"
  11. #include "apr_thread_cond.h"

  12. #include <deque>
  13. #include <assert.h>

  14. ////////////////////////////////////////////////////////////////////////////
  15. namespace comn
  16. {
  17.         template <class A>
  18.         class CQueue
  19.         {
  20.         public:               
  21.                 CQueue();       
  22.                 ~CQueue();

  23.                 ///压入一个元素
  24.                 void push(const A &item);                                        //for producer

  25.                 bool pop(A &item);                                                        //for consumer

  26.                 bool popTimeWait(A &item,int millisec);     //for consumer

  27.                 size_t  size();     //队列大小
  28.                 bool    empty();    ///判为空

  29.                 void    post(); ///激活资源获取者
  30.        
  31.         private:               
  32.                 std::deque<A> m_queue;    ///stl deque

  33.                 apr_pool_t *m_aprBasePool;
  34.                 apr_thread_mutex_t *m_mutex;   ///线程锁
  35.                 apr_thread_cond_t *m_cond;     ///条件变量
  36.         };


  37.         template <class A>
  38.         CQueue<A>::CQueue()
  39.         {       
  40.                 apr_status_t ret;
  41.                 ret = apr_pool_create(&m_aprBasePool,NULL);               
  42.                 if (ret != APR_SUCCESS)
  43.                 {
  44.                         assert(0);
  45.                 }

  46.                 ///线程锁
  47.                 ret = apr_thread_mutex_create(&m_mutex,APR_THREAD_MUTEX_DEFAULT,m_aprBasePool);       
  48.                 if (ret != APR_SUCCESS)
  49.                 {
  50.                         assert(0);
  51.                 }

  52.                 ///条件变量
  53.                 ret = apr_thread_cond_create(&m_cond, m_aprBasePool);       
  54.                 if (ret != APR_SUCCESS)
  55.                 {
  56.                         assert(0);
  57.                 }
  58.                 m_queue.clear();
  59.         }



  60.         template <class A>
  61.         CQueue<A>::~CQueue()
  62.         {
  63.                 m_queue.clear();
  64.                 apr_thread_mutex_destroy(m_mutex);
  65.                 apr_thread_cond_destroy(m_cond);
  66.                 apr_pool_destroy(m_aprBasePool);
  67.         }

  68.         template <class A>
  69.         void CQueue<A>::push(const A &item)
  70.         {
  71.                 apr_thread_mutex_lock(m_mutex);                               
  72.                 m_queue.push_back(item);        ///数据放入队列
  73.                 apr_thread_mutex_unlock(m_mutex);

  74.                 //唤醒一个线程
  75.                 apr_thread_cond_signal(m_cond);   
  76.                 return ;
  77.         }


  78.         template <class A>
  79.         void CQueue<A>::post()
  80.         {       
  81.                 apr_thread_cond_signal(m_cond);
  82.         }


  83.         template <class A>
  84.         size_t CQueue<A>::size()
  85.         {
  86.                 apr_thread_mutex_lock(m_mutex);       
  87.                 size_t s = m_queue.size();
  88.                 apr_thread_mutex_unlock(m_mutex);       
  89.                 return s;
  90.         }

  91.         template <class A>
  92.         bool CQueue<A>::empty()
  93.         {               
  94.                 return size() == 0;
  95.         }

  96.         template <class A>
  97.         bool CQueue<A>::pop(A &item)
  98.         {       
  99.                 apr_thread_mutex_lock(m_mutex);       
  100.                 while (m_queue.empty())
  101.                 {       
  102.                         //线程睡眠解锁,等待唤醒
  103.                         apr_thread_cond_wait(m_cond,m_mutex);  
  104.                 }       

  105.                 if(m_queue.empty())
  106.                 {       
  107.                         apr_thread_mutex_unlock(m_mutex);
  108.                         return false;
  109.                 }

  110.                 item = m_queue.front();  ///取头元素
  111.                 m_queue.pop_front();     ///弹出头元素       

  112.                 apr_thread_mutex_unlock(m_mutex);
  113.                 return true;
  114.         }

  115.         template <class A>
  116.         bool CQueue<A>::popTimeWait(A &item,int millisec)
  117.         {       
  118.                 apr_thread_mutex_lock(m_mutex);

  119.                 while (m_queue.empty())
  120.                 {               
  121.                         //线程睡眠解锁,等待唤醒或者超时
  122.                         apr_status_t ret = apr_thread_cond_timedwait(m_cond,m_mutex,millisec);

  123.                         if (ret == APR_TIMEUP)      ///超时了
  124.                         {
  125.                                 apr_thread_mutex_unlock(m_mutex);
  126.                                 return false;
  127.                         }
  128.                 }               

  129.                 item = m_queue.front();  ///取头元素
  130.                 m_queue.pop_front();       

  131.                 apr_thread_mutex_unlock(m_mutex);

  132.                 return true;
  133.         }

  134. }
  135. ////////////////////////////////////////////////////////////////////////////
  136. #endif /* TQUEUE_H_ */
复制代码

论坛徽章:
0
8 [报告]
发表于 2010-11-07 18:21 |只看该作者
多线程互斥锁使用实现:信号量 Semaphore


入队列input信号量 +1
出队列output信号量 -1
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP