您的位置:首页 > 其它

boost进程间通信经常使用开发一篇全(消息队列,共享内存,信号)

2015-04-29 12:17 453 查看

本文概要:

敏捷开发大家想必知道并且评价甚高,缩短开发周期,提高开发质量。将大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\n",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


将消息队列整理了一下,能够直接方便使用例如以下:

注(BoostMsg.h)用于将函数外部化,无其它用处。

#include <BoostMsg.h>

#include <boost/interprocess/ipc/message_queue.hpp>
#include <iostream>
#include <vector>

using namespace boost::interprocess;

int BoostMsg_CreateMsg(const char* MsgQueName,int MaxQueLen,int MaxMsgLen)
{
message_queue::remove(MsgQueName);
//Create a message_queue.
message_queue mq
(create_only               //only create
,MsgQueName						//name
,MaxQueLen                       //max message number
,MaxMsgLen              //max message size
);

printf("Boost Msg Created Name:%s QueLen:%d MsgMaxLen:%d \n",MsgQueName,MaxQueLen,MaxMsgLen);

return 0;
}

int BoostMsg_OpenMsgToSend(char* BufMsg,const char* MsgQueName,int MsgLen)
{
try{
//Erase previous message queue
//message_queue::remove("message_queue");
//Create a message_queue.
message_queue mq
(open_only               //only create
,MsgQueName						//name
);

mq.send(BufMsg, MsgLen, 0);
}
catch(interprocess_exception &ex){
std::cout << ex.what() << std::endl;
return 1;
}
return 0;
}

int BoostMsg_OpenMsgToRec(char* RecivedMsg,const char* MsgQueName,int MaxReceivedLen)
{
try{
//Open a message queue.
message_queue mq
(open_only        //only create
,MsgQueName  //name
);

unsigned int priority;
message_queue::size_type recvd_size;

memset(RecivedMsg,0,MaxReceivedLen);
mq.receive(RecivedMsg, MaxReceivedLen, recvd_size, priority);
return recvd_size;

}
catch(interprocess_exception &ex){
message_queue::remove("message_queue");
std::cout << ex.what() << std::endl;
return 1;
}
message_queue::remove("message_queue");
return 0;
}


用法非常easy,就是Create 然后Send 和Rec,进程之间通信 非常方便。

參考文章:

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

/article/1359124.html

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐