免费注册 查看新帖 |

Chinaunix

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

[C++] 改写 gtkmm 的线程为 boost 线程 [复制链接]

论坛徽章:
24
狮子座
日期:2013-12-31 10:48:0015-16赛季CBA联赛之吉林
日期:2016-04-18 14:43:1015-16赛季CBA联赛之北控
日期:2016-05-18 15:01:4415-16赛季CBA联赛之上海
日期:2016-06-22 18:00:1315-16赛季CBA联赛之八一
日期:2016-06-25 11:02:2215-16赛季CBA联赛之佛山
日期:2016-08-17 22:48:2615-16赛季CBA联赛之福建
日期:2016-12-27 22:39:272016科比退役纪念章
日期:2017-02-08 23:49:4315-16赛季CBA联赛之八一
日期:2017-02-16 01:05:3415-16赛季CBA联赛之山东
日期:2017-02-22 15:34:5615-16赛季CBA联赛之上海
日期:2017-11-25 16:17:5015-16赛季CBA联赛之四川
日期:2016-01-17 18:38:37
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2016-01-27 21:39 |只看该作者 |倒序浏览
本帖最后由 zhujiang73 于 2016-01-27 21:55 编辑

         
         以前写 gtkmm 程序,线程一般是这样的:
  1. #include <iostream>
  2. #include <queue>
  3. #include <glibmm/threads.h>
  4. #include <glibmm/random.h>
  5. #include <glibmm/timer.h>
  6. #include <glibmm/init.h>
  7. namespace
  8. {
  9. class MessageQueue
  10. {
  11. public:
  12.     MessageQueue();
  13.     ~MessageQueue();
  14.     void producer();
  15.     void consumer();
  16. private:
  17.     Glib::Threads::Mutex mutex_;
  18.     Glib::Threads::Cond cond_push_;
  19.     Glib::Threads::Cond cond_pop_;
  20.     std::queue<int> queue_;
  21. };
  22. MessageQueue::MessageQueue()
  23. {}
  24. MessageQueue::~MessageQueue()
  25. {}
  26. void MessageQueue::producer()
  27. {
  28.     Glib::Rand rand (1234);
  29.     for(auto i = 0; i < 200; ++i)
  30.     {
  31.         {
  32.             Glib::Threads::Mutex::Lock lock (mutex_);
  33.             while(queue_.size() >= 64)
  34.                 cond_pop_.wait(mutex_);
  35.             queue_.push(i);
  36.             std::cout << '*';
  37.             std::cout.flush();
  38.             cond_push_.signal();
  39.         }
  40.         if(rand.get_bool())
  41.             continue;
  42.         Glib::usleep(rand.get_int_range(0, 100000));
  43.     }
  44. }
  45. void MessageQueue::consumer()
  46. {
  47.     Glib::Rand rand (4567);
  48.     for(;;)
  49.     {
  50.         {
  51.             Glib::Threads::Mutex::Lock lock (mutex_);
  52.             while(queue_.empty())
  53.                 cond_push_.wait(mutex_);
  54.             const int i = queue_.front();
  55.             queue_.pop();
  56.             std::cout << "\x08 \x08";
  57.             std::cout.flush();
  58.             cond_pop_.signal();
  59.             if(i >= 199)
  60.                 break;
  61.         }
  62.         if(rand.get_bool())
  63.             continue;
  64.         Glib::usleep(rand.get_int_range(10000, 200000));
  65.     }
  66. }
  67. }
  68. int main(int, char**)
  69. {
  70.     Glib::init();
  71.     MessageQueue queue;
  72.     Glib::Threads::Thread *const producer = Glib::Threads::Thread::create(
  73.             sigc::mem_fun(queue, &MessageQueue::producer));
  74.     Glib::Threads::Thread *const consumer = Glib::Threads::Thread::create(
  75.             sigc::mem_fun(queue, &MessageQueue::consumer));
  76.     producer->join();
  77.     consumer->join();
  78.     std::cout << std::endl;
  79.     return 0;
  80. }
复制代码
现在想改用 boost 的线程。

论坛徽章:
24
狮子座
日期:2013-12-31 10:48:0015-16赛季CBA联赛之吉林
日期:2016-04-18 14:43:1015-16赛季CBA联赛之北控
日期:2016-05-18 15:01:4415-16赛季CBA联赛之上海
日期:2016-06-22 18:00:1315-16赛季CBA联赛之八一
日期:2016-06-25 11:02:2215-16赛季CBA联赛之佛山
日期:2016-08-17 22:48:2615-16赛季CBA联赛之福建
日期:2016-12-27 22:39:272016科比退役纪念章
日期:2017-02-08 23:49:4315-16赛季CBA联赛之八一
日期:2017-02-16 01:05:3415-16赛季CBA联赛之山东
日期:2017-02-22 15:34:5615-16赛季CBA联赛之上海
日期:2017-11-25 16:17:5015-16赛季CBA联赛之四川
日期:2016-01-17 18:38:37
2 [报告]
发表于 2016-01-27 21:45 |只看该作者
zhujiang73 发表于 2016-01-27 21:39
以前写 gtkmm 程序,线程一般是这样的:现在想改用 boost 的线程。



      查了些资料之后我写成这样了,写对了么?
  1. #ifndef MCVTHREAD_H
  2. #define MCVTHREAD_H

  3. #include <boost/thread/thread.hpp>
  4. #include <boost/thread/mutex.hpp>
  5. #include <boost/thread/shared_mutex.hpp>
  6. #include <boost/thread/condition.hpp>
  7. #include <boost/function/function0.hpp>

  8. #include <glibmm.h>
  9. #include <algorithm>
  10. #include <functional>
  11. #include <iostream>
  12. #include <vector>
  13. #include <queue>
  14. #include <string>
  15. #include <unistd.h>

  16. class  WebWin;

  17. class  McvThread
  18. {
  19. public:
  20.     McvThread(){};
  21.     ~McvThread(){};

  22. protected:
  23.     Glib::Dispatcher            signal_thread;
  24.     std::queue<std::string>     str_queue_events;
  25.     //Glib::Threads::Mutex      mcv_mutex;
  26.     boost::shared_mutex         shr_mutex;
  27.     boost::condition            cond;

  28.     int   num;

  29. public:
  30.     void setup(WebWin  *p_webwin);
  31.     void start();
  32.     void get_str_event(std::string  &str_event);

  33. protected:
  34.     void fun();
  35. };


  36. #endif // MCVTHREAD_H
复制代码
  1. #include "webwin/webwin.h"
  2. #include "mcvthread/mcvthread.h"

  3. #include <cstdlib>
  4. #include <cstring>
  5. #include <cstdio>

  6. void McvThread::setup(WebWin  *p_webwin)
  7. {
  8.     num = 0;
  9.     signal_thread.connect(sigc::bind<1>(sigc::mem_fun(*p_webwin, &WebWin::on_thread_signal), this));
  10. }

  11. void McvThread::fun()
  12. {
  13.     for (int i=0; i<200; i++)
  14.     {
  15.         for (int i=0; i<10; i++) usleep(100*1000);

  16.         //usleep(1000);

  17.         //sleep(1);

  18.         num++;

  19.         char           ch_text[1024];
  20.         std::string    str_text;

  21.         shr_mutex.lock();

  22.         if (str_queue_events.size() > 0)  cond.wait(shr_mutex);

  23.         {
  24.             snprintf(ch_text, 1000, "Thread num : %d    ", num);
  25.             str_text = ch_text;
  26.             snprintf(ch_text, 1000, "queue_events.size : %d    ", str_queue_events.size());
  27.             str_text += ch_text;
  28.             str_queue_events.push(str_text);
  29.         }

  30.         shr_mutex.unlock();

  31.         signal_thread();
  32.     }
  33. }

  34. void McvThread::start()
  35. {
  36.     boost::function0<void> f = boost::bind(&McvThread::fun, this);
  37.     boost::thread thrd(f);
  38. }

  39. void McvThread::get_str_event(std::string  &str_event)
  40. {
  41.     shr_mutex.lock();
  42.     //shr_mutex.lock_shared();

  43.     if (str_queue_events.size() > 0)
  44.     {
  45.         str_event = str_queue_events.front();
  46.         str_queue_events.pop();
  47.     }
  48.     shr_mutex.unlock();
  49.     //shr_mutex.unlock_shared();

  50.     cond.notify_one();
  51. }

复制代码
  1.     McvThread  *p_mcv_thread = new McvThread();

  2.     //p_mcv_thread->signal_thread.connect(sigc::mem_fun(*this, &WebWin::on_thread_signal));

  3.     p_mcv_thread->setup(this);
  4.     p_mcv_thread->start();
复制代码

  1. void WebWin::on_thread_signal(McvThread  *p_mcv_thread)
  2. {
  3.     std::string  str_event = "";

  4.     p_mcv_thread->get_str_event(str_event);

  5.     std::cout << str_event << std::endl;
  6. }
复制代码

论坛徽章:
89
水瓶座
日期:2014-04-01 08:53:31天蝎座
日期:2014-04-01 08:53:53天秤座
日期:2014-04-01 08:54:02射手座
日期:2014-04-01 08:54:15子鼠
日期:2014-04-01 08:55:35辰龙
日期:2014-04-01 08:56:36未羊
日期:2014-04-01 08:56:27戌狗
日期:2014-04-01 08:56:13亥猪
日期:2014-04-01 08:56:02亥猪
日期:2014-04-08 08:38:58程序设计版块每日发帖之星
日期:2016-01-05 06:20:00程序设计版块每日发帖之星
日期:2016-01-07 06:20:00
3 [报告]
发表于 2016-01-28 08:48 |只看该作者
貌似,只要gtkmm库的代码运行在自己的thread上就行了,至于用哪个库的thread都不是问题吧。

论坛徽章:
89
水瓶座
日期:2014-04-01 08:53:31天蝎座
日期:2014-04-01 08:53:53天秤座
日期:2014-04-01 08:54:02射手座
日期:2014-04-01 08:54:15子鼠
日期:2014-04-01 08:55:35辰龙
日期:2014-04-01 08:56:36未羊
日期:2014-04-01 08:56:27戌狗
日期:2014-04-01 08:56:13亥猪
日期:2014-04-01 08:56:02亥猪
日期:2014-04-08 08:38:58程序设计版块每日发帖之星
日期:2016-01-05 06:20:00程序设计版块每日发帖之星
日期:2016-01-07 06:20:00
4 [报告]
发表于 2016-01-28 08:49 |只看该作者
我写的gtkmm的程序,好像都是用的boost的线程。

论坛徽章:
24
狮子座
日期:2013-12-31 10:48:0015-16赛季CBA联赛之吉林
日期:2016-04-18 14:43:1015-16赛季CBA联赛之北控
日期:2016-05-18 15:01:4415-16赛季CBA联赛之上海
日期:2016-06-22 18:00:1315-16赛季CBA联赛之八一
日期:2016-06-25 11:02:2215-16赛季CBA联赛之佛山
日期:2016-08-17 22:48:2615-16赛季CBA联赛之福建
日期:2016-12-27 22:39:272016科比退役纪念章
日期:2017-02-08 23:49:4315-16赛季CBA联赛之八一
日期:2017-02-16 01:05:3415-16赛季CBA联赛之山东
日期:2017-02-22 15:34:5615-16赛季CBA联赛之上海
日期:2017-11-25 16:17:5015-16赛季CBA联赛之四川
日期:2016-01-17 18:38:37
5 [报告]
发表于 2016-01-28 16:39 |只看该作者
本帖最后由 zhujiang73 于 2016-01-28 16:39 编辑
fender0107401 发表于 2016-01-28 08:49
我写的gtkmm的程序,好像都是用的boost的线程。



      我现在是工作线程用 boost 线程实现,但是工作线程向 GUI 线程发消息是用 Gtkmm 中的 Glib Dispatcher 跨线程消息机制。

      程序跑起来也没发现什么问题,就是不知道 Gtkmm 和 Boost 配合使用时有没有坑?    

论坛徽章:
89
水瓶座
日期:2014-04-01 08:53:31天蝎座
日期:2014-04-01 08:53:53天秤座
日期:2014-04-01 08:54:02射手座
日期:2014-04-01 08:54:15子鼠
日期:2014-04-01 08:55:35辰龙
日期:2014-04-01 08:56:36未羊
日期:2014-04-01 08:56:27戌狗
日期:2014-04-01 08:56:13亥猪
日期:2014-04-01 08:56:02亥猪
日期:2014-04-08 08:38:58程序设计版块每日发帖之星
日期:2016-01-05 06:20:00程序设计版块每日发帖之星
日期:2016-01-07 06:20:00
6 [报告]
发表于 2016-01-28 18:33 |只看该作者
回复 5# zhujiang73

差不多,我也是这么弄的。

我在gui里面弄了个带锁的队列,每次发消息就往队列里面加一个事务,然后emit一下,让处理事务的代码去处理一个事务,而且处理的时候是运行在gui的线程上面。

   

论坛徽章:
24
狮子座
日期:2013-12-31 10:48:0015-16赛季CBA联赛之吉林
日期:2016-04-18 14:43:1015-16赛季CBA联赛之北控
日期:2016-05-18 15:01:4415-16赛季CBA联赛之上海
日期:2016-06-22 18:00:1315-16赛季CBA联赛之八一
日期:2016-06-25 11:02:2215-16赛季CBA联赛之佛山
日期:2016-08-17 22:48:2615-16赛季CBA联赛之福建
日期:2016-12-27 22:39:272016科比退役纪念章
日期:2017-02-08 23:49:4315-16赛季CBA联赛之八一
日期:2017-02-16 01:05:3415-16赛季CBA联赛之山东
日期:2017-02-22 15:34:5615-16赛季CBA联赛之上海
日期:2017-11-25 16:17:5015-16赛季CBA联赛之四川
日期:2016-01-17 18:38:37
7 [报告]
发表于 2016-01-28 22:55 |只看该作者
本帖最后由 zhujiang73 于 2016-01-28 22:55 编辑

回复 6# fender0107401


   
Glib Dispatcher works similar to sigc::signal<void>. But unlike normal signals, the notification happens asynchronously through a pipe.



    这个跨线程的异步消息,看起来就是个进程间通信机制。不知道 Boost 里有没有类似的东西?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP