redisclient
redisclient copied to clipboard
mutil thread asyncclient error
class IoService
{
public:
IoService(int threadNum = 1) : m_io{},
m_work(new boost::asio::io_service::work(m_io))
{
for (int i = 0; i < threadNum; i++)
{
auto th = std::make_shared<boost::thread>(boost::bind(&boost::asio::io_service::run, &m_io));
m_threadPool.push_back(th);
}
};
~IoService()
{
m_work.reset();
//m_io.stop();
for (auto &t : m_threadPool)
{
t->join();
}
m_threadPool.clear();
}
boost::asio::io_service &service()
{
return m_io;
}
private:
boost::asio::io_service m_io;
std::shared_ptr<boost::asio::io_service::work> m_work;
std::vector<std::shared_ptr<boost::thread>> m_threadPool;
};
int main(int argc, char **argv)
{
std::shared_ptr<IoService> io(new IoService(10));
auto cli = std::make_shared<redisclient::RedisAsyncClient>(io->service());
boost::asio::ip::tcp::endpoint end(boost::asio::ip::address::from_string("127.0.0.1"), 6379);
cli->connect(end, [](boost::system::error_code err) {
if (!err) //connect error
{
printf("connect success\n");
}
else
{
printf("connect error %d\n", err);
}
});
std::this_thread::sleep_for(std::chrono::seconds(1));
for (int i = 0; i < 100; i++)
{
cli->command("set", {"name", "zhangsan"}, [](redisclient::RedisValue value) {
if (value.isOk())
{
printf("success\n");
}
else
{
printf("failed\n");
}
});
}
while(1)
{
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
output error: connect success success success success success success success success success success main: malloc.c:2394: sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed. Aborted (core dumped)
not run in mutil thread io service?
I tried the similar stuffs the other day before. I found it's tricky and it may depend on what OS or what boost versions. For Ubuntu 20.04, multi-thread with single io_context variables (but shared that event processor across threads as your code, it seems to work fine. However, on CentOS 8, that does not work unless you assign each thread a standalone io_cotext, which means, each redisAsyncClient must consume its own event processor... otherwise, it can cause segmentation fault, which means.... maybe not thread-safe...
Not deep dive but it is quite annoyed.
A single instance redisclient cannot be used from multiple threads. Use signle redisclient per thread or one thread with a redisclient for all other threads.