redisclient icon indicating copy to clipboard operation
redisclient copied to clipboard

mutil thread asyncclient error

Open ai0376 opened this issue 4 years ago • 2 comments

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?

ai0376 avatar Jan 23 '21 05:01 ai0376

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.

leeee-me avatar Feb 24 '21 09:02 leeee-me

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.

nekipelov avatar Feb 24 '21 10:02 nekipelov