Boost Message Queue可以处理的最大大小是多少?
当我使用Boost二进制序列化发送和接收以下结构时,它工作正常。
typedef struct {
int msg_type;
char msg_name[100];
union {
struct {
int ID;
std::string ReportedTime;
char ReceivedAt[200];
int Number;
int Priority;
} mess1;
struct {
char host_ip[20];
char mac_addr[30];
char time_stamp[100];
} mess2;
} struct_type;
}msg_struct;
#include <boost/serialization/is_bitwise_serializable.hpp>
BOOST_IS_BITWISE_SERIALIZABLE(msg_struct)
但是当我将ReceivedAt[2000]
的大小设置为2000或添加一个新的char数组变量时。
它抛出以下异常并且核心被倾倒。
terminate called after throwing an instance of 'boost::interprocess::interprocess_exception'
what(): boost::interprocess_exception::library_error
Aborted (core dumped)
修改
发送
int ControlQueue::pushMessage(msg_struct* msg)
{
int q_size = vamsgq->get_num_msg();
int retVal = 0;
lockQueue();
//imp->ID=1;
//strcpy(imp->ReceivedAt,"10-07-14");
std::stringstream oss;
boost::archive::binary_oarchive oa(oss);
strncpy(msg->msg_name,"msg_name",sizeof(msg->msg_name));
oa << boost::serialization::make_array(msg, 1);
std::string serialized_string(oss.str());
vamsgq->send(serialized_string.data(), serialized_string.size(), 0);
std::cout <<"\n sendig type="<< msg->msg_name << std::endl;
if((retVal = pthread_cond_signal(&m_qCondSignal)) != 0)
{
cout<<__FILE__<<__LINE__<<
"{ControlQueue %x} Unable to send Cond Signal",this);
}
unlockQueue();
return 1;
}
收到:
msg_struct* ControlQueue::getMsg()
{
int retVal = 0;
message_queue::size_type recvd_size;
unsigned int priority;
lockQueue();
while(vamsgq->get_num_msg()==0)
{
if((retVal = pthread_cond_wait(&m_qCondSignal, &m_qMutex)) != 0)
{
cout<<__FILE__<<__LINE__<<"getMsg {ControlQueue } Unable to Cond Signal";
unlockQueue();
return NULL;
}
}
msg_struct *l_msg_struct = NULL;
if(vamsgq->get_num_msg())
{
l_msg_struct=new msg_struct();
std::stringstream iss;
std::string serialized_string;
serialized_string.resize(MAX_SIZE);
vamsgq->receive(&serialized_string[0], MAX_SIZE, recvd_size, priority);
iss << serialized_string;
boost::archive::binary_iarchive ia(iss);
ia >> boost::serialization::make_array(l_msg_struct, 1);
std::cout <<"Recieving="<< l_msg_struct->msg_name << std::endl;
}
else
{
cout<<__FILE__<<__LINE__<<"getMsg {ControlQueue } m_MsgQ empty..";
}
unlockQueue();
return l_msg_struct;
}
发送和接收都在不同的线程中运行,我得到的唯一问题是在增加结构的大小或添加char数组变量之后。
异常是由vamsgq->send()
方法抛出,Creation方法(消息队列)工作正常。而且我还增加了消息队列将要存储的Message的大小。
boost :: message_queue是否有完整的在线文档。
答案 0 :(得分:4)
你打破了
的要求BOOST_IS_BITWISE_SERIALIZABLE(msg_struct)
不再保持msg_struct
POD类型:
static_assert(boost::is_pod<msg_struct>::value, "msg_struct must be POD");
将无法编译。 (事实上,使用msg_struct
显示的std::string
,我认为默认构造应该无法编译,因此示例中的new msg_struct()
行会让我感到困惑。
此外,您不显示消息队列的结构,因此我无法确定您如何确定最大消息大小。这可能没有足够的尺寸。请参阅下文,了解使用/检查大小限制的两种方法。
以下是可行的:
#include <boost/serialization/serialization.hpp>
#include <boost/interprocess/ipc/message_queue.hpp>
typedef struct {
int msg_type;
char msg_name[100];
union {
struct {
int ID;
char ReportedTime[100];
char ReceivedAt[2000];
int Number;
int Priority;
} mess1;
struct {
char host_ip[20];
char mac_addr[30];
char time_stamp[100];
} mess2;
} struct_type;
} msg_struct;
static_assert(boost::is_pod<msg_struct>::value, "msg_struct must be POD");
#include <boost/serialization/is_bitwise_serializable.hpp>
BOOST_IS_BITWISE_SERIALIZABLE(msg_struct)
namespace ipc = boost::interprocess;
int main() {
ipc::message_queue queue(ipc::open_or_create, "myqueue", 100, sizeof(msg_struct));
msg_struct outgoing;
outgoing.msg_type = 1;
strncpy(outgoing.msg_name, "outgoing.msg_name", sizeof(outgoing.msg_name));
outgoing.struct_type.mess1.ID = 42;
strncpy(outgoing.struct_type.mess1.ReportedTime, "outgoing.struct_type.mess1.ReportedTime", sizeof(outgoing.struct_type.mess1.ReportedTime));
strncpy(outgoing.struct_type.mess1.ReceivedAt, "outgoing.struct_type.mess1.ReceivedAt", sizeof(outgoing.struct_type.mess1.ReceivedAt));
outgoing.struct_type.mess1.Number = 123;
outgoing.struct_type.mess1.Priority = 234;
queue.send(&outgoing, sizeof(outgoing), 1);
}
正如您所看到的,这不是使用Boost序列化,因为结构是POD无论如何。
或者,您可以一直使用Boost序列化和检查邮件大小在发送时是否超过最大邮件大小:
#include <boost/serialization/serialization.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/serialization/variant.hpp>
#include <boost/interprocess/ipc/message_queue.hpp>
typedef struct {
int msg_type;
std::string msg_name;
struct mess1_t {
int ID;
std::string ReportedTime;
std::string ReceivedAt;
int Number;
int Priority;
private:
friend class boost::serialization::access;
template <typename Ar>
void serialize(Ar& ar, unsigned)
{
ar & ID;
ar & ReportedTime;
ar & ReceivedAt;
ar & Number;
ar & Priority;
}
};
struct mess2_t {
std::string host_ip;
std::string mac_addr;
std::string time_stamp;
private:
friend class boost::serialization::access;
template <typename Ar>
void serialize(Ar& ar, unsigned)
{
ar & host_ip;
ar & mac_addr;
ar & time_stamp;
}
};
boost::variant<mess1_t, mess2_t> message_data;
private:
friend class boost::serialization::access;
template <typename Ar>
void serialize(Ar& ar, unsigned)
{
ar & msg_type;
ar & msg_name;
ar & message_data;
}
} msg_struct;
namespace ipc = boost::interprocess;
int main() {
ipc::message_queue queue(ipc::open_or_create, "myqueue", 100, 4*1024);
msg_struct outgoing { 1, "outgoing.msg_name", msg_struct::mess1_t {
42,
"outgoing.struct_type.mess1.ReportedTime",
"outgoing.struct_type.mess1.ReceivedAt",
123,
234 }
};
std::ostringstream oss;
boost::archive::binary_oarchive oa(oss);
oa << outgoing;
assert(oss.str().size() <= queue.get_max_msg_size());
queue.send(&outgoing, sizeof(outgoing), 1);
}