Chinaunix首页 | 论坛 | 博客
  • 博客访问: 579710
  • 博文数量: 104
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1559
  • 用 户 组: 普通用户
  • 注册时间: 2014-08-21 00:58
个人简介

锻炼精神,首先要锻炼肉体

文章分类

全部博文(104)

文章存档

2018年(1)

2016年(1)

2015年(101)

2014年(1)

我的朋友

分类: C/C++

2015-06-08 15:16:57

在试着翻译学习前几篇 boost 在线文档之后,编写了个小型的用于进程间通信 (IPC) 的文件队列。
该文件队列是使用 std::vector 封装文件中的内容。
并将封装了文件内容的 vector 按照 map 散列表的方式存放到共享内存空间中供多个进程使用.

程序简单流程的描述如下:
主进程创建并打开共享内存空间,并将各个文件读入到共享内存空间中

紧接着,依次打开多个子进程,每个子进程访问 共享内存空间中的文件队列中不同名的文件,(由于没有涉及到互斥访问,所以没有加锁)
将其内容打印到屏幕上面,之后子进程结束

主进程,释放内存空间中文件队列中的每个元素,释放共享内存空间,进程结束



实例代码如下:

// IPC.h

点击(此处)折叠或打开

  1. #ifndef IPC_H_
  2. #define IPC_H_

  3. #include <string>
  4. #include <vector>
  5. #include <memory>

  6. #include "boost/interprocess/managed_shared_memory.hpp"
  7. #include "boost/interprocess/containers/string.hpp"

  8. namespace bi = boost::interprocess ;

  9. typedef bi::allocator<char ,bi::managed_shared_memory::segment_manager> CharAllocator;
  10. typedef bi::basic_string<char , std::char_traits<char> , CharAllocator> bi_string ;


  11. class IPC
  12. {
  13. public :

  14.   // in this file reads in file name
  15.   IPC (std::string &shm_name ) ;
  16.   ~IPC () ;

  17.  /*
  18.     open each file by name (path) which stored in file_name_list_
  19.     and reads file's content one after another writes it into the shared-memory
  20.  */
  21.     
  22.   int init_shared_memory() ;    


  23.   /**
  24.     this method is used to write into the file with name of file_name stored inside shared memory
  25.     with the name of shm_name_
  26.   */
  27.   int writter (std::string &file_name ) ;
  28.     
  29.   /**
  30.     and this method is read the file 's contents from the shared memory
  31.     prints it onto the screen
  32.   */
  33.   int reader ( std::string &file_name ) ;
  34.  
  35.   int remove_shared_mem () ;
  36.   int create_shared_mem () ;
  37.   
  38.   int get_file_num ()
  39.   {
  40.     return file_name_list_.size() ;
  41.   }
  42.     
  43. private :
  44.   std::string shm_name_ ;
  45.   std::vector<std::string> file_name_list_ ;
  46.     
  47. } ;


  48. #endif

// IPC.cpp

点击(此处)折叠或打开

  1. #include "IPC.h"

  2. #include <cstdio>
  3. #include <iostream>
  4. #include <cstring>
  5. #include <fstream>


  6. using namespace std ;

  7. IPC::IPC( std::string &shared_mem_name )
  8. {

  9.   shm_name_ = shared_mem_name ;

  10. }

  11. //---------------------------------------------

  12. /**
  13.   in create_shared_mem we create a shared memory
  14.   
  15.   from official online documents
  16.   we create a shared memory as two basic steps:
  17.   
  18.   1. create a managed_shared_memory instance
  19.   
  20.   2. create a special type of allocator ( in this test we use the char's special allocator )
  21.      if we want to shared memory organized like a STL
  22.      constructor and allocates the space from the shared-memory
  23.      dynamically
  24.  
  25.   however , here , we just create shared memory ,
  26.   until method init_shared_memory we write file's contents into
  27.   the shared memory , so we do not need step2 here
  28. */


  29. int IPC::create_shared_mem ()
  30. {
  31.   // before we create a shared memory , we should call the remove first in case of
  32.  // it already exist , this will cause an error happend during running time
  33.     remove_shared_mem () ;

  34.   boost::interprocess::managed_shared_memory
  35.         shm ( boost::interprocess::create_only ,
  36.             shm_name_.c_str() , 65536/2 ) ;
  37.   return 0 ;
  38. }

  39. //-----------------------------------------------------

  40. int IPC::init_shared_memory ()
  41. {
  42.     /*
  43.      here we gonna to initialize the shared_memory
  44.      we would like create the shared memory like this
  45.      
  46.     | file-name | file-contents |
  47.     | ..... | ..... |
  48.    */    

  49.   int num ;
  50.   string name ;

  51.   cout << "input how many files and their names which you want to shared them into shared memory"<< endl ;
  52.   cout << "how many" << endl ;
  53.   cin >> num ;

  54.   for ( int i = 0 ; i < num ; i++ )
  55.   {
  56.         cout << "file name " << endl ;
  57.         cin >> name ;

  58.         file_name_list_.push_back ( name ) ;
  59.   }    
  60.    

  61.    // here we create a shared_memory_manager
  62.    boost::interprocess::managed_shared_memory shm (boost::interprocess::open_only ,
  63.         shm_name_.c_str() ) ;
  64.     
  65.     // here is basic step 2 , create an allocator instance
  66.     // CharAllocator is user defined char's allocator
  67.    // allocates space from shared memory object

  68.     CharAllocator charallocator( shm.get_segment_manager() ) ;
  69.  
  70.    
  71.  // in the following cycle , we open each file ,
  72. // and output the file's content into shared memory

  73.     for ( size_t i(0) ; i < file_name_list_.size() ; i++)    
  74.     {
  75.     fstream i_file ;
  76.     i_file.open ( file_name_list_[i].c_str(),ios::in | ios::binary ) ;
  77.        
  78.         if ( !i_file.is_open())
  79.         {
  80.          perror ("[error] open file failed") ;
  81.         return -1 ;    
  82.     }
  83.    
  84.     // here we read each file contents 256 bytes each time ,
  85.     // and writes the bytes into the shared memory

  86.     string file_content ;
  87.     char file_buffer [256] ;    

  88.     while ( !i_file.eof())
  89.     {
  90.         memset ( file_buffer, '\0' , sizeof(file_buffer)) ;
  91.         i_file.getline(file_buffer, 256 ) ;
  92.         file_content += file_buffer ;
  93.     }
  94.     
  95.     // here we finish reading a whole file's content
  96.     // next , we transfer the string type into
  97.     // boost::interprocess::basic_string type    
  98.  
  99.     i_file.close() ;
  100.  
  101.     bi_string bi_file_conent (charallocator) ;
  102.     bi_file_conent = file_content.c_str() ;
  103.     shm.construct<bi_string>(file_name_list_[i].c_str())(bi_file_conent) ;
  104.     
  105.    } // for cycle

  106.    return 0 ;
  107. }

  108. //-------------------------------------------------------
  109. int IPC::reader( string &file_name )
  110. {
  111.     // fist we need to open the shared memory object by target name
  112.     boost::interprocess::managed_shared_memory shm
  113.         ( boost::interprocess::open_only ,shm_name_.c_str()) ;
  114.     
  115.     // then we use the opened memory manager to create
  116.     // a user-defined allocator type's instance

  117.     CharAllocator charallocator( shm.get_segment_manager()) ;
  118.     
  119.     // then we use the user-defined allocator instance create
  120.        // user-defined type
  121.     bi_string str(charallocator) ;
  122.     
  123.     string file_content ;
  124.     

  125.     std::pair<bi_string*,boost::interprocess::managed_shared_memory::size_type>res
  126.         = shm.find<bi_string>( file_name.c_str() ) ;

  127.     cout << "in IPC' reader 's file name " << file_name << endl ;
  128.         
  129.     if ( res.first == NULL )
  130.     {
  131.         perror ("[error] failed find target file in shared memory") ;
  132.         return -1 ;
  133.     }
  134.     
  135.     file_content = string(res.first->c_str() , res.first->size() ) ;
  136.      
  137.     
  138.     cout << "here is the file's content " << endl ;
  139.      cout << file_content << endl ;    

  140.     return 0 ;
  141. }

  142. //--------------------------------------------------------
  143. int IPC::remove_shared_mem ()
  144. {

  145.   boost::interprocess::shared_memory_object::remove(shm_name_.c_str() ) ;
  146.     
  147.   return 0;
  148. }

  149. //-------------------------------------------------------------
  150. IPC::~IPC()
  151. {
  152.     remove_shared_mem () ;
  153. }

// Process.h

点击(此处)折叠或打开

  1. #ifndef PROCESS_H_
  2. #define PROCESS_H_

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

  6. #include "IPC.h"

  7. class Process
  8. {
  9.   public :
  10.     Process ( std::string &_name , std::string &_shared_mem_name, bool isMain) ;    
  11.     ~Process ( ) ;
  12.     int runProc ( std::string & file_name ) ;
  13.     int getSharedFileNum ()
  14.     {
  15.         if ( isMain ) return ipc->get_file_num () ;
  16.         else return 0 ;
  17.     }    

  18.   private :
  19.     IPC *ipc ;
  20.     std::string name ;
  21.     std::string shared_mem_name ;
  22.     
  23.     bool isMain ;
  24. } ;


  25. #endif
// Process.cpp

点击(此处)折叠或打开

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <iostream>

  4. #include "Processor.h"

  5. using namespace std ;


  6. Process::Process ( std::string& _name , std::string& _shared_mem_name , bool _isMain ):name(_name )
  7.         ,shared_mem_name(_shared_mem_name ), isMain(_isMain)
  8. {
  9.     ipc = new IPC( shared_mem_name ) ; // here we create a ipc instance
  10. }


  11. Process::~Process ()
  12. {
  13.     // if this is the Main process , release the shared memory
  14.     if ( isMain)
  15.     {
  16.         ipc->remove_shared_mem () ;
  17.         cout << "now we remove shared memory by main process" << endl ;
  18.     }
  19.     else
  20.      cout << "sub process exit" << endl ;
  21.     
  22. }

  23. int Process::runProc ( std::string &file_name )
  24. {
  25.     // here we gonna to run the process
  26.     if ( isMain )
  27.     {
  28.         ipc->create_shared_mem() ;
  29.         ipc->init_shared_memory() ;
  30.     }
  31.     return ipc->reader (file_name ) ;
  32.     
  33. }
// Main.cpp

点击(此处)折叠或打开

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <iostream>

  4. #include "IPC.h"
  5. #include "Processor.h"

  6. using namespace std ;

  7. int main( int argc , char *argv [] )
  8. {
  9.     std::string shared_memory_name = "Aimer" ;
  10.     std::string file_name = "/tmp/rsa_key" ;    

  11.     /*
  12.            // tests for class IPC
  13.     
  14.     IPC ipc ( shared_memory_name ) ;
  15.     
  16.     if (ipc.create_shared_mem () )
  17.     {
  18.         perror ("create_shared_mem failed ") ;
  19.         return -1 ;
  20.     }
  21.     
  22.     if (ipc.init_shared_memory () )
  23.     {    
  24.         perror ("init_shared_memory failed ") ;
  25.         return -1 ;
  26.     }
  27.     
  28.     if ( ipc.reader( file_name ) )
  29.     {
  30.         perror ("reader method failed ") ;
  31.         return -1 ;
  32.     }
  33.     cout << endl ;
  34.     cout <<"------------------ here we gonna test another IPC node visit shared memory's content-----------------" << endl ;
  35.     IPC ipc2 (shared_memory_name ) ;
  36.     ipc2.reader(file_name) ;
  37.     
  38.    */    
  39.     // test for class Process
  40.     
  41.     std::string proc_name = "main " ;
  42.     
  43.     
  44.        
  45.     Process mainProc (proc_name , shared_memory_name, true ) ;

  46.     
  47.     string new_file_name = file_name +"0.txt" ;    

  48.     cout <<"-------------------------- main process running ------------------------" << endl ;

  49.     mainProc.runProc (new_file_name) ;    

  50.     
  51.     cout <<" ------------------ sub process running ----------------------------" << endl ;

  52.     for ( int i = 1 ; i < mainProc.getSharedFileNum() ; i++ )
  53.     {
  54.         proc_name = "sub_proc " ;
  55.         Process subProc (proc_name, shared_memory_name , false ) ;
  56.         
  57.         char no = i +'0' ;
  58.         new_file_name = file_name+no+".txt" ;

  59.         cout << endl ;
  60.         
  61.         cout <<"---------------- sub process run "<< i << "------------------------"<< endl ;
  62.         subProc.runProc(new_file_name) ;
  63.     
  64.         cout <<"---------------- sub process " << i << "end---------------------------" <<endl ;
  65.     }



  66.     cout << "end of main "<< endl ;
  67.     return 0 ;
  68. }

// Makefile.am

点击(此处)折叠或打开

  1. AUTOMAKE_OPTIONS=foreign
  2. bin_PROGRAMS=file_ipc

  3. BOOST_PATH=/unixC/Boost/boost_1_58_0

  4. #add source files
  5. file_ipc_SOURCES=\
  6.     IPC.h IPC.cpp Processor.cpp Processor.h Main.cpp

  7. file_ipc_CXXFLAGS=\
  8.     -I$(BOOST_PATH) -D_FILE_OFFSET_BITS=64 -ggdb -Wall -O0

  9. file_ipc_LDADD=\
  10.     -lpthread -lm -lboost_system -lboost_thread \
  11.     -lboost_thread -lboost_program_options -lrt

  12. file_ipc_LDFLAGS=\
  13.     -fPIC -rdynamic -L$(BOOST_PATH)/stage/lib -pthread

如果没有错误的话,运行结果差不多是这样的(我读入的文件是前几篇文章中调用 openssl 函数库生成的 rsa 公钥文件)


end

阅读(3589) | 评论(2) | 转发(0) |
给主人留下些什么吧!~~

夏目玲子2015-06-28 15:22:31

夏目玲子:这个 Process 模拟进程不是很好,完全体现不出来 process 并发的效果,以后使用 linux 中的进程来实现

you can you do , no bb

回复 | 举报

夏目玲子2015-06-08 15:44:50

这个 Process 模拟进程不是很好,完全体现不出来 process 并发的效果,以后使用 linux 中的进程来实现