Advertisement
Guest User

Untitled

a guest
Jan 13th, 2011
812
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.37 KB | None | 0 0
  1. #include <boost/python.hpp>
  2. #include <boost/thread.hpp>
  3. #include <iostream>
  4. #include <sstream>
  5. #include <queue>
  6.  
  7. class Keeper
  8. {
  9. boost::python::object main_module;
  10. boost::python::object main_namespace;
  11.  
  12. boost::mutex peacekeeper;
  13.  
  14. public:
  15.     boost::mutex python_keeper;
  16.    
  17.     Keeper()
  18.     {
  19.         boost::mutex::scoped_lock l(this->peacekeeper);
  20.  
  21.         Py_Initialize();
  22.        
  23.         this->main_module = boost::python::import("__main__");
  24.         this->main_namespace = main_module.attr("__dict__");
  25.  
  26.         try
  27.         {
  28.             boost::python::exec_file(boost::python::str("test.py"), this->main_namespace);
  29.         } catch (boost::python::error_already_set const &)
  30.         {
  31.             PyErr_Print();
  32.             abort;
  33.         }
  34.     };
  35.  
  36.     template <typename T>
  37.     T Get(std::string object)
  38.     {
  39.         boost::mutex::scoped_lock l(this->peacekeeper);
  40.  
  41.         try
  42.         {
  43.             return boost::python::extract<T>(object, this->main_namespace);
  44.         } catch (boost::python::error_already_set const &)
  45.         {
  46.             PyErr_Print();
  47.             abort();
  48.         }
  49.     };
  50. };
  51.  
  52. template<>
  53. boost::python::object Keeper::Get<boost::python::object>(std::string object)
  54. {
  55.     boost::mutex::scoped_lock l(this->peacekeeper);
  56.  
  57.     try
  58.     {
  59.         return this->main_namespace[object];
  60.     } catch (boost::python::error_already_set const &)
  61.     {
  62.         PyErr_Print();
  63.         abort();
  64.     }
  65. }
  66.  
  67. class Queue
  68. {
  69. std::queue<int> kept;
  70. boost::mutex peacekeeper;
  71. int size_;
  72.  
  73. public:
  74.     Queue()
  75.     {
  76.         this->size_ = 0;
  77.     };
  78.  
  79.     void give(int i)
  80.     {
  81.         boost::mutex::scoped_lock l(this->peacekeeper);
  82.         this->kept.push(i);
  83.  
  84.         this->size_ += 1;
  85.     };
  86.  
  87.     int take()
  88.     {
  89.         boost::mutex::scoped_lock l(this->peacekeeper);
  90.  
  91.         int tmp = this->kept.front();
  92.         this->kept.pop();
  93.  
  94.         this->size_ -= 1;
  95.  
  96.         return tmp;
  97.     }
  98.  
  99.     int size()
  100.     {
  101.         return this->size_;
  102.     };
  103. };
  104.  
  105. class Producer
  106. {
  107. Queue *myqueue;
  108. Keeper *k;
  109. int id;
  110.  
  111. public:
  112.     Producer(Queue *myqueue, Keeper *k, int id)
  113.     {
  114.         this->myqueue = myqueue;
  115.         this->k = k;
  116.         this->id = id;
  117.     };
  118.  
  119.     void run()
  120.     {
  121.         int i = 0;
  122.         while (true)
  123.         {
  124.             this->myqueue->give(i);
  125.  
  126.             boost::python::object writer = this->k->Get<boost::python::object>("write");
  127.            
  128.             std::ostringstream os;
  129.             os << ">>> PRODUCER " << id << " give " << i << std::endl;
  130.  
  131.             {
  132.                 boost::mutex::scoped_lock l(this->k->python_keeper);
  133.                 writer(boost::python::str(os.str()));
  134.             }
  135.  
  136.             boost::xtime xt;
  137.             boost::xtime_get(&xt, boost::TIME_UTC);
  138.             xt.sec += 1;
  139.  
  140.             i += 1;
  141.  
  142.             boost::thread::sleep(xt);
  143.         }
  144.     }
  145. };
  146.  
  147. class Consumer
  148. {
  149. Queue *myqueue;
  150. Keeper *k;
  151.  
  152. public:
  153.     Consumer(Queue *myqueue, Keeper *k)
  154.     {
  155.         this->myqueue = myqueue;
  156.         this->k = k;
  157.     };
  158.  
  159.     void run()
  160.     {
  161.         while (true)
  162.         {
  163.             if (this->myqueue->size() > 0)
  164.             {
  165.                 int tmp = this->myqueue->take();
  166.  
  167.                 boost::python::object writer = this->k->Get<boost::python::object>("write");
  168.                
  169.                 std::ostringstream os;
  170.                 os << "<<< CONSUMER get " << tmp << std::endl;
  171.                
  172.                 {
  173.                     boost::mutex::scoped_lock l(this->k->python_keeper);
  174.                     writer(boost::python::str(os.str()));
  175.                 }
  176.             }
  177.  
  178.             boost::xtime xt;
  179.             boost::xtime_get(&xt, boost::TIME_UTC);
  180.             xt.nsec += 10000;
  181.  
  182.             boost::thread::sleep(xt);
  183.         }
  184.     };
  185. };
  186.  
  187. struct ConsumerThread
  188. {
  189.     Consumer *c;
  190.  
  191.     void operator()()
  192.     {
  193.         c->run();
  194.     };
  195. };
  196.  
  197. struct ProducerThread
  198. {
  199.     Producer *p;
  200.  
  201.     void operator()()
  202.     {
  203.         p->run();
  204.     };
  205. };
  206.  
  207. int main()
  208. {
  209.     Keeper k;
  210.     Queue q;
  211.  
  212.     boost::thread_group grp;
  213.  
  214.     ConsumerThread cons;
  215.     cons.c = new Consumer(&q, &k);
  216.     grp.create_thread(cons);
  217.    
  218.     for (int i = 0; i < 3; i++)
  219.     {
  220.         ProducerThread prod;
  221.         prod.p = new Producer(&q, &k, i);
  222.         grp.create_thread(prod);
  223.     }
  224.  
  225.     grp.join_all();
  226. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement