关键词:BOOST MQ 消息队列 线程间通信 性能测试 VS2022
有关如何使用boost可参考文章:
当我使用消息队列,我担心一个问题:使用消息队列将会带来多少性能损失。那么实测一下boost中的消息队列在线程间通信的时间开销。
结论:BOOST MQ不适合只有单条消息传递的情形,更适合解决批量生产和消费(并发)。
1 BOOST MQ用法简介
包含头文件并指定外部包含目录
#include <boost/interprocess/ipc/message_queue.hpp>
使用命名空间
Using namespace boost::interprocess;
创建一个队列
message_queue mq(create_only,"name",10 ,100,permissions());
向队列传递
mq.send(const void *buffer, size_type buffer_size, unsigned int priority);
从队列取出
mq.receive(void *buffer, size_type buffer_size,size_type &recvd_size,unsigned int &priority);
2 测试目的
使用线程间、进程间通信时,MQ所花费的时间开销,用于评估系统架构性能
3 测试方法
3.1连续调用
客户端:
启动计时并发送100万条消息
服务端:
接收100万条消息并终止计时
3.2单次调用
客户端:
启动计时并发送
接收并结束计时
服务端:
接收消息
发送消息
4 测试结果
计算平均每次时间花费
5 辅助工具
借助boost::timer进行计时。Boost::timer使用方法参考文章:
6 测试代码(连续调用)
#include <iostream>
#include <thread>
#include <boost/timer/timer.hpp>
#include <boost/interprocess/ipc/message_queue.hpp>
using namespace boost::interprocess;
using namespace boost::timer;
cpu_timer myTimer;
int testTimes = 1000000;
void client()
{
message_queue mq(open_only, "name");
boost::ulong_long_type recvd_size;
unsigned int priority;
char buffer[20];
while(1)
{
for ( int i = 0; i < testTimes; i++)
{
mq.receive(buffer, 20, recvd_size, priority);
}
myTimer.stop();
auto cost_time = myTimer.elapsed();
std::cout << "billion cost time total = " << cost_time.wall / 1000000.0 << " ms.\n";
std::cout << "billion cost time per = " << cost_time.wall / 1000.0 / testTimes << " us.\n";
Sleep(500);
}
}
void server()
{
message_queue mq(open_or_create,"name",1000,20,permissions());
char buffer[6] = "Hello";
//start client
std::thread clientThread{ client };
while (1)
{
myTimer.start();
for (int i = 0; i < testTimes; i++)
{
mq.send(buffer,6,0);
}
Sleep(3000);
}
clientThread.join();
message_queue::remove("name");
}
int main()
{
std::cout << "Hello BOOST MQ!\n";
std::thread myTask{ server };
myTask.join();
std::cout << "Bye BOOST MQ!\n";
}
7 测试代码(单次调用)
#include <iostream>
#include <thread>
#include <boost/timer/timer.hpp>
#include <boost/interprocess/ipc/message_queue.hpp>
using namespace boost::interprocess;
using namespace boost::timer;
cpu_timer myTimer;
int testTimes = 1;
void client()
{
message_queue mq(open_only, "name");
boost::ulong_long_type recvd_size;
unsigned int priority;
char buffer[20];
while(1)
{
for ( int i = 0; i < testTimes; i++)
{
mq.receive(buffer, 20, recvd_size, priority);
}
myTimer.stop();
auto cost_time = myTimer.elapsed();
std::cout << "Cost time total = " << cost_time.wall / 1000000.0 << " ms.\n";
std::cout << "Cost time per = " << cost_time.wall / 1000.0 / testTimes << " us.\n";
Sleep(500);
}
}
void server()
{
message_queue::remove("name");
message_queue mq(open_or_create,"name",1000,20,permissions());
char buffer[6] = "Hello";
//start client
std::thread clientThread{ client };
while (1)
{
myTimer.start();
for (int i = 0; i < testTimes; i++)
{
mq.send(buffer,6,0);
}
Sleep(3000);
}
clientThread.join();
}
int main()
{
std::cout << "Hello BOOST MQ!\n";
std::thread myTask{ server };
myTask.join();
std::cout << "Bye BOOST MQ!\n";
}
8 测试结论
8.1 连续调用平均单次约1us,相当于异步调用。
8.2 单次调用所产生的时间开销较多,可能数十毫秒,或者数十微秒。
因此在时间严格微秒级别的本地串行调用上,不可用BOOST MQ。换种说法:BOOST MQ 不适合只有一条消息传递的情形,更适合批量消息的生产和消费。
9 问题与验证
消息队列的大小是否影响性能?
生产者->生产-> 消息队列(容量1-100万进行分别测试) 消费者->消费-> ?
测试结论:影响存在,但微乎
10 在进程间通信性能如何?
测试结论:基本符合线程间的测试结果。
如果问题,可以留言给我。