首页 新闻 搜索 专区 学院

boost asio ioservice 多线程并发做TCP 服务

0
[已解决问题] 解决于 2018-12-11 16:39
int main()
{
    boost::asio::io_service io_svc;
    std::vector<std::thread> vecThread;
    for (int i = 0; i < 5; ++i)
    {
        vecThread.emplace_back(std::thread([](){ io_svc.run(); }));
    }

    return 0;
}

 

如果按上面的代码将一个io_svc 分配多个线程按并发处理,处理的对象是TCP 服务时。发现对同一个TCP 客户端的连接的处理会在多个线程中。

如果是这样的话,那这一个客户端发送过来数据被分成多段后,在服务端会不会乱,而这样我是不是需要加锁控制,可如果加锁的话又应该怎么加呢?

按时我的想法是,如果 是同一个话,它如果只在同一个线程中那么这个我就不用担心了,因为它会顺序到达,那么我收到的头部和数据部就不会被分到两个线程中去了。

这主要问题是TCP 服务端使用异步的方式接收客户端的数据,首先收到固定的头部数据,然后解析头部得到数据部的长度,然后再次异步接收实际的数据。如果这两个步骤被分到了两个线程中去了。导致了这两个部分发生了并发操作,那就尴尬了。

独孤酷酷的主页 独孤酷酷 | 菜鸟二级 | 园豆:204
提问于:2017-06-29 14:50
< >
分享
最佳答案
0

单个线程用于数据接收,放到一个队列,开多个消费线程用于数据处理

奖励园豆:5
飞鸿眉敛 | 菜鸟二级 |园豆:256 | 2017-06-30 15:29

每一次接收都有一个处理函数,这个处理函数是自己提供的。而这个处理函数提供了之后,如果没有再次添加异步读的话,那么这个连接将不会继续到TCP 上去读取数据,这个连接的TCP 上的数据将会被存起来,直到你调用异步或者同步读。
而这里的正确处理方式应该是:在每次读的处理函数结束之后,再去读TCP 上面的数据,这样一个连接就会一直按顺序去TCP 上读取数据,而不需要加锁。当然了,如果你的处理函数中先添加了异步读,再添加了数据处理代码,那就有可能会有问题。在这个时候就可能存在,你在处理数据的时候,异步读调用了新的处理函数。那么这种代码是不可取的,所以正确的处理应该是将读到的数据处理完成之后,再添加下一个异步读。而不是像你说的那个再多开几个消费线程,这样在逻辑上就会比较乱,同时多开了线程必然导致锁的增加,也必然存在锁的消耗。

独孤酷酷 | 园豆:204 (菜鸟二级) | 2018-12-11 16:39
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册