在试着翻译学习前几篇 boost 在线文档之后,编写了个小型的用于进程间通信 (IPC) 的文件队列。
该文件队列是使用 std::vector 封装文件中的内容。
并将封装了文件内容的 vector 按照 map 散列表的方式存放到共享内存空间中供多个进程使用.
程序简单流程的描述如下:
主进程创建并打开共享内存空间,并将各个文件读入到共享内存空间中
紧接着,依次打开多个子进程,每个子进程访问 共享内存空间中的文件队列中不同名的文件,(由于没有涉及到互斥访问,所以没有加锁)
将其内容打印到屏幕上面,之后子进程结束
主进程,释放内存空间中文件队列中的每个元素,释放共享内存空间,进程结束
实例代码如下:
// IPC.h
-
#ifndef IPC_H_
-
#define IPC_H_
-
-
#include <string>
-
#include <vector>
-
#include <memory>
-
-
#include "boost/interprocess/managed_shared_memory.hpp"
-
#include "boost/interprocess/containers/string.hpp"
-
-
namespace bi = boost::interprocess ;
-
-
typedef bi::allocator<char ,bi::managed_shared_memory::segment_manager> CharAllocator;
-
typedef bi::basic_string<char , std::char_traits<char> , CharAllocator> bi_string ;
-
-
-
class IPC
-
{
-
public :
-
-
// in this file reads in file name
-
IPC (std::string &shm_name ) ;
-
~IPC () ;
-
-
/*
-
open each file by name (path) which stored in file_name_list_
-
and reads file's content one after another writes it into the shared-memory
-
*/
-
-
int init_shared_memory() ;
-
-
-
/**
-
this method is used to write into the file with name of file_name stored inside shared memory
-
with the name of shm_name_
-
*/
-
int writter (std::string &file_name ) ;
-
-
/**
-
and this method is read the file 's contents from the shared memory
-
prints it onto the screen
-
*/
-
int reader ( std::string &file_name ) ;
-
-
int remove_shared_mem () ;
-
int create_shared_mem () ;
-
-
int get_file_num ()
-
{
-
return file_name_list_.size() ;
-
}
-
-
private :
-
std::string shm_name_ ;
-
std::vector<std::string> file_name_list_ ;
-
-
} ;
-
-
-
#endif
// IPC.cpp
-
#include "IPC.h"
-
-
#include <cstdio>
-
#include <iostream>
-
#include <cstring>
-
#include <fstream>
-
-
-
using namespace std ;
-
-
IPC::IPC( std::string &shared_mem_name )
-
{
-
-
shm_name_ = shared_mem_name ;
-
-
}
-
-
//---------------------------------------------
-
-
/**
-
in create_shared_mem we create a shared memory
-
-
from official online documents
-
we create a shared memory as two basic steps:
-
-
1. create a managed_shared_memory instance
-
-
2. create a special type of allocator ( in this test we use the char's special allocator )
-
if we want to shared memory organized like a STL
-
constructor and allocates the space from the shared-memory
-
dynamically
-
-
however , here , we just create shared memory ,
-
until method init_shared_memory we write file's contents into
-
the shared memory , so we do not need step2 here
-
*/
-
-
-
int IPC::create_shared_mem ()
-
{
-
// before we create a shared memory , we should call the remove first in case of
-
// it already exist , this will cause an error happend during running time
-
remove_shared_mem () ;
-
-
boost::interprocess::managed_shared_memory
-
shm ( boost::interprocess::create_only ,
-
shm_name_.c_str() , 65536/2 ) ;
-
return 0 ;
-
}
-
-
//-----------------------------------------------------
-
-
int IPC::init_shared_memory ()
-
{
-
/*
-
here we gonna to initialize the shared_memory
-
we would like create the shared memory like this
-
-
| file-name | file-contents |
-
| ..... | ..... |
-
*/
-
-
int num ;
-
string name ;
-
-
cout << "input how many files and their names which you want to shared them into shared memory"<< endl ;
-
cout << "how many" << endl ;
-
cin >> num ;
-
-
for ( int i = 0 ; i < num ; i++ )
-
{
-
cout << "file name " << endl ;
-
cin >> name ;
-
-
file_name_list_.push_back ( name ) ;
-
}
-
-
-
// here we create a shared_memory_manager
-
boost::interprocess::managed_shared_memory shm (boost::interprocess::open_only ,
-
shm_name_.c_str() ) ;
-
-
// here is basic step 2 , create an allocator instance
-
// CharAllocator is user defined char's allocator
-
// allocates space from shared memory object
-
-
CharAllocator charallocator( shm.get_segment_manager() ) ;
-
-
-
// in the following cycle , we open each file ,
-
// and output the file's content into shared memory
-
-
for ( size_t i(0) ; i < file_name_list_.size() ; i++)
-
{
-
fstream i_file ;
-
i_file.open ( file_name_list_[i].c_str(),ios::in | ios::binary ) ;
-
-
if ( !i_file.is_open())
-
{
-
perror ("[error] open file failed") ;
-
return -1 ;
-
}
-
-
// here we read each file contents 256 bytes each time ,
-
// and writes the bytes into the shared memory
-
-
string file_content ;
-
char file_buffer [256] ;
-
-
while ( !i_file.eof())
-
{
-
memset ( file_buffer, '\0' , sizeof(file_buffer)) ;
-
i_file.getline(file_buffer, 256 ) ;
-
file_content += file_buffer ;
-
}
-
-
// here we finish reading a whole file's content
-
// next , we transfer the string type into
-
// boost::interprocess::basic_string type
-
-
i_file.close() ;
-
-
bi_string bi_file_conent (charallocator) ;
-
bi_file_conent = file_content.c_str() ;
-
shm.construct<bi_string>(file_name_list_[i].c_str())(bi_file_conent) ;
-
-
} // for cycle
-
-
return 0 ;
-
}
-
-
//-------------------------------------------------------
-
int IPC::reader( string &file_name )
-
{
-
// fist we need to open the shared memory object by target name
-
boost::interprocess::managed_shared_memory shm
-
( boost::interprocess::open_only ,shm_name_.c_str()) ;
-
-
// then we use the opened memory manager to create
-
// a user-defined allocator type's instance
-
-
CharAllocator charallocator( shm.get_segment_manager()) ;
-
-
// then we use the user-defined allocator instance create
-
// user-defined type
-
bi_string str(charallocator) ;
-
-
string file_content ;
-
-
-
std::pair<bi_string*,boost::interprocess::managed_shared_memory::size_type>res
-
= shm.find<bi_string>( file_name.c_str() ) ;
-
-
cout << "in IPC' reader 's file name " << file_name << endl ;
-
-
if ( res.first == NULL )
-
{
-
perror ("[error] failed find target file in shared memory") ;
-
return -1 ;
-
}
-
-
file_content = string(res.first->c_str() , res.first->size() ) ;
-
-
-
cout << "here is the file's content " << endl ;
-
cout << file_content << endl ;
-
-
return 0 ;
-
}
-
-
//--------------------------------------------------------
-
int IPC::remove_shared_mem ()
-
{
-
-
boost::interprocess::shared_memory_object::remove(shm_name_.c_str() ) ;
-
-
return 0;
-
}
-
-
//-------------------------------------------------------------
-
IPC::~IPC()
-
{
-
remove_shared_mem () ;
-
}
// Process.h
-
#ifndef PROCESS_H_
-
#define PROCESS_H_
-
-
#include <cstdio>
-
#include <cstring>
-
#include <iostream>
-
-
#include "IPC.h"
-
-
class Process
-
{
-
public :
-
Process ( std::string &_name , std::string &_shared_mem_name, bool isMain) ;
-
~Process ( ) ;
-
int runProc ( std::string & file_name ) ;
-
int getSharedFileNum ()
-
{
-
if ( isMain ) return ipc->get_file_num () ;
-
else return 0 ;
-
}
-
-
private :
-
IPC *ipc ;
-
std::string name ;
-
std::string shared_mem_name ;
-
-
bool isMain ;
-
} ;
-
-
-
#endif
// Process.cpp
-
#include <cstdio>
-
#include <cstring>
-
#include <iostream>
-
-
#include "Processor.h"
-
-
using namespace std ;
-
-
-
Process::Process ( std::string& _name , std::string& _shared_mem_name , bool _isMain ):name(_name )
-
,shared_mem_name(_shared_mem_name ), isMain(_isMain)
-
{
-
ipc = new IPC( shared_mem_name ) ; // here we create a ipc instance
-
}
-
-
-
Process::~Process ()
-
{
-
// if this is the Main process , release the shared memory
-
if ( isMain)
-
{
-
ipc->remove_shared_mem () ;
-
cout << "now we remove shared memory by main process" << endl ;
-
}
-
else
-
cout << "sub process exit" << endl ;
-
-
}
-
-
int Process::runProc ( std::string &file_name )
-
{
-
// here we gonna to run the process
-
if ( isMain )
-
{
-
ipc->create_shared_mem() ;
-
ipc->init_shared_memory() ;
-
}
-
return ipc->reader (file_name ) ;
-
-
}
// Main.cpp
-
#include <cstdio>
-
#include <cstring>
-
#include <iostream>
-
-
#include "IPC.h"
-
#include "Processor.h"
-
-
using namespace std ;
-
-
int main( int argc , char *argv [] )
-
{
-
std::string shared_memory_name = "Aimer" ;
-
std::string file_name = "/tmp/rsa_key" ;
-
-
/*
-
// tests for class IPC
-
-
IPC ipc ( shared_memory_name ) ;
-
-
if (ipc.create_shared_mem () )
-
{
-
perror ("create_shared_mem failed ") ;
-
return -1 ;
-
}
-
-
if (ipc.init_shared_memory () )
-
{
-
perror ("init_shared_memory failed ") ;
-
return -1 ;
-
}
-
-
if ( ipc.reader( file_name ) )
-
{
-
perror ("reader method failed ") ;
-
return -1 ;
-
}
-
cout << endl ;
-
cout <<"------------------ here we gonna test another IPC node visit shared memory's content-----------------" << endl ;
-
IPC ipc2 (shared_memory_name ) ;
-
ipc2.reader(file_name) ;
-
-
*/
-
// test for class Process
-
-
std::string proc_name = "main " ;
-
-
-
-
Process mainProc (proc_name , shared_memory_name, true ) ;
-
-
-
string new_file_name = file_name +"0.txt" ;
-
-
cout <<"-------------------------- main process running ------------------------" << endl ;
-
-
mainProc.runProc (new_file_name) ;
-
-
-
cout <<" ------------------ sub process running ----------------------------" << endl ;
-
-
for ( int i = 1 ; i < mainProc.getSharedFileNum() ; i++ )
-
{
-
proc_name = "sub_proc " ;
-
Process subProc (proc_name, shared_memory_name , false ) ;
-
-
char no = i +'0' ;
-
new_file_name = file_name+no+".txt" ;
-
-
cout << endl ;
-
-
cout <<"---------------- sub process run "<< i << "------------------------"<< endl ;
-
subProc.runProc(new_file_name) ;
-
-
cout <<"---------------- sub process " << i << "end---------------------------" <<endl ;
-
}
-
-
-
-
cout << "end of main "<< endl ;
-
return 0 ;
-
}
// Makefile.am
-
AUTOMAKE_OPTIONS=foreign
-
bin_PROGRAMS=file_ipc
-
-
BOOST_PATH=/unixC/Boost/boost_1_58_0
-
-
#add source files
-
file_ipc_SOURCES=\
-
IPC.h IPC.cpp Processor.cpp Processor.h Main.cpp
-
-
file_ipc_CXXFLAGS=\
-
-I$(BOOST_PATH) -D_FILE_OFFSET_BITS=64 -ggdb -Wall -O0
-
-
file_ipc_LDADD=\
-
-lpthread -lm -lboost_system -lboost_thread \
-
-lboost_thread -lboost_program_options -lrt
-
-
file_ipc_LDFLAGS=\
-
-fPIC -rdynamic -L$(BOOST_PATH)/stage/lib -pthread
如果没有错误的话,运行结果差不多是这样的(我读入的文件是前几篇文章中调用 openssl 函数库生成的 rsa 公钥文件)
end
阅读(3589) | 评论(2) | 转发(0) |