zoukankan      html  css  js  c++  java
  • boost进程间通信经常使用开发一篇全(消息队列,共享内存,信号)

    本文概要:

            敏捷开发大家想必知道并且评价甚高,缩短开发周期,提高开发质量。将大project独立为不同的小app开发,整个开发过程,程序可用可測,所以提高了总体的质量。基于这样的开发模式和开发理念,进程间通信必定是童鞋们必掌握技能之中的一个了,而boost库是众多库中平台支持性非常好,效果非常高之中的一个。做嵌入式或者server等应用的人肯定有所涉及。本文以手冊方式讲述boost共享内存,信号,以及消息队列的编程方式。非常easy,列出最经常使用使用方法,供大家拷贝直接使用。本文出自CSDN-固本培元。转载注明出处-leoluopy@gmail.com。

    应用思路注意事项:

             信号是进程内通信,非常类似于Qt的信号槽,配合消息队列以及boost多线程使用效果非常好。

    共享内存:

    #include <boost/interprocess/shared_memory_object.hpp>  
    #include <boost/interprocess/mapped_region.hpp>  
    #include <cstring>  
    #include <cstdlib>  
    #include <string>  
       
    int main(int argc, char *argv[])  
    {  
       using namespace boost::interprocess;  
       
       if(argc == 1){  //Parent process  
          //Remove shared memory on construction and destruction  
          struct shm_remove  
          {  
             shm_remove() { shared_memory_object::remove("MySharedMemory"); }  
             ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }  
          } remover;  
       
          //Create a shared memory object.  
          shared_memory_object shm (create_only, "MySharedMemory", read_write);  
       
          //Set size  
          shm.truncate(1000);  
       
          //Map the whole shared memory in this process  
          mapped_region region(shm, read_write);  
       
          //Write all the memory to 1  
          std::memset(region.get_address(), 1, region.get_size());  
       
          //Launch child process  
          std::string s(argv[0]); s += " child ";  
          if(0 != std::system(s.c_str()))  
             return 1;  
       }  
       else{  
          //Open already created shared memory object.  
          shared_memory_object shm (open_only, "MySharedMemory", read_only);  
       
          //Map the whole shared memory in this process  
          mapped_region region(shm, read_only);  
       
          //Check that memory was initialized to 1  
          char *mem = static_cast<char*>(region.get_address());  
          for(std::size_t i = 0; i < region.get_size(); ++i)  
             if(*mem++ != 1)  
                return 1;   //Error checking memory  
       }  
       return 0;  
    } 


    信号通信:

    贴出一个经常使用带參数的写法,具体的其它使用方法能够參考文章末的參考文章:

    #include <boost/signal.hpp>
    
    #include <boost/thread/thread.hpp>
    
    #include <boost/date_time/posix_time/posix_time.hpp>
    
    #include <iostream>
    
     
    
    using namespace std;
    
    using namespace boost;
    
     
    
    float print_sum(float x, float y)
    
    {
    
      std::cout << "The sum is " << x+y << std::endl;
    
      return x+y;
    
    }
    
     
    
    float print_product(float x, float y)
    
    {
    
      std::cout << "The product is " << x*y << std::endl;
    
      return x*y;
    
    }
    
     
    
    float print_difference(float x, float y)
    
    {
    
      std::cout << "The difference is " << x-y << std::endl;
    
      return x-y;
    
    }
    
     
    
    float print_quotient(float x, float y)
    
    {
    
      std::cout << "The quotient is " << x/y << std::endl;
    
      return x/y;
    
    }
    
     
    
    int main()
    
    {
    
      boost::signal<float (float , float )> sig;
    
      sig.connect(0, &print_sum);
    
      sig.connect(1, &print_product);
    
      sig.connect(2, &print_difference);
    
      sig.connect(3, &print_quotient);
    
      // Output 1.6667 because return by the last slot called.
    
      cout << sig(5, 3) << endl;   
    
      return 0;
    
    }

    信号槽删除及堵塞:

    Seg 1: Disconnecting slots.
    
            boost::signals::connection c = sig.connect(HelloWorld());
    
            if (c.connected()) {
    
            // c is still connected to the signal
    
            sig(); // Prints "Hello, World!"
    
            }
    
            c.disconnect(); // Disconnect the HelloWorld object
    
            assert(!c.connected()); //c isn't connected any more
    
            sig(); // Does nothing: there are no connected slots
    
    Seg 2:
    
            boost::signals::connection c = sig.connect(HelloWorld());
    
            sig(); // Prints "Hello, World!"
    
     
    
            c.block(); // block the slot
    
            assert(c.blocked());
    
            sig(); // No output: the slot is blocked
    
     
    
            c.unblock(); // unblock the slot
    
            sig(); // Prints "Hello, World!"




    消息队列:

    消息队列发送:

    #include <boost/interprocess/ipc/message_queue.hpp>
    #include <iostream>
    #include <vector>
    
    using namespace boost::interprocess;
    
    int main ()
    {
       try{
          //Erase previous message queue
          message_queue::remove("message_queue");
    
          //Create a message_queue.
          message_queue mq
             (create_only               //only create
             ,"message_queue"           //name
             ,100                       //max message number
             ,sizeof(int)               //max message size
             );
    
          //Send 100 numbers
          for(int i = 0; i < 100; ++i){
             mq.send(&i, sizeof(i), 0);
          }
    
    
       }
       catch(interprocess_exception &ex){
          std::cout << ex.what() << std::endl;
          return 1;
       }
    
       return 0;
    }

    消息队列接收:

    #include <boost/interprocess/ipc/message_queue.hpp>
    #include <iostream>
    #include <vector>
    
    using namespace boost::interprocess;
    
    int main ()
    {
       try{
          //Open a message queue.
          message_queue mq
             (open_only        //only create
             ,"message_queue"  //name
             );
    
          unsigned int priority;
          message_queue::size_type recvd_size;
    
          //Receive 100 numbers
          for(int i = 0; i < 100; ++i)
    	  {
             int number;
             mq.receive(&number, sizeof(number), recvd_size, priority);
    		 printf("I:%d Rec:%d
    ",i,number);
             if(number != i || recvd_size != sizeof(number))
                return 1;
          }
       }
       catch(interprocess_exception &ex){
          message_queue::remove("message_queue");
          std::cout << ex.what() << std::endl;
          return 1;
       }
       message_queue::remove("message_queue");
       return 0;
    }


    编译命令:


    [root@localhost tmp]# g++ boost_queue_send.cpp -o queue_send -lboost_thread -lboost_system
    [root@localhost tmp]# g++ boost_queue_rec.cpp -o queue_rec -lboost_thread -lboost_system



    參考文章:

    Boost.Interprocess使用手冊翻译之四:在进程间共享内存 (Sharing memory between processes)

    http://blog.csdn.net/great3779/article/details/7226388

    Windows多进程编程

    http://blog.csdn.net/bxhj3014/article/details/2082255

    怎样使用BOOST信号(一)

    http://blog.csdn.net/liuchangyu23/article/details/4584045

    Boost.Interprocess 强大的进程间通讯库

    http://blog.csdn.net/linkerlin/article/details/2249906

    怎样使用BOOST信号(二)

    http://blog.csdn.net/liuchangyu23/article/details/4584346









  • 相关阅读:
    「ROI 2019 Day1」运输 20/19
    「ROI 2018 Day 2」无进位加法
    「ROI 2018 Day 1」量子隐形传态
    「ROI 2018 Day 2」快速排序
    「ROI 2018 Day 1」Innophone (分块+斜率优化)
    「ROI 2017 Day 1」虎 (计算几何)
    [BJ United Round #3] 押韵 [学习笔记]
    「CEOI2020」象棋世界
    CF1375G
    CF1392(div1+div2)
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/3763402.html
Copyright © 2011-2022 走看看