Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mutil thread asyncclient error #80

Open
ai0376 opened this issue Jan 23, 2021 · 2 comments
Open

mutil thread asyncclient error #80

ai0376 opened this issue Jan 23, 2021 · 2 comments

Comments

@ai0376
Copy link

ai0376 commented Jan 23, 2021

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?

@leeee-me
Copy link

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.

@nekipelov
Copy link
Owner

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants