使用 boost 套接字,我只需要一个 io_service 吗?

2024-02-17

在几个不同的线程中有多个连接..我基本上正在做一个使用 boost/asio.hpp 和那里的 tcp 东西的基类.. 现在我正在读这个:http://www.boost.org/doc/libs/1_44_0/doc/html/boost_asio/tutorial/tutdaytime1.html http://www.boost.org/doc/libs/1_44_0/doc/html/boost_asio/tutorial/tutdaytime1.html它说“所有使用 asio 的程序都需要至少有一个 io_service 对象”。 所以我的基类应该有一个静态 io_service (这意味着所有程序只有 1 个,并且所有不同的线程和连接将使用相同的 io_service 对象) 或者让每个连接都有自己的io_service?

谢谢前面!

更新: 好吧,基本上我想做的是一个基本客户端的类,它将有一个套接字。 对于每个套接字,我将有一个始终接收的线程和一个有时发送数据包的不同线程。 在这里查看后:www.boost.org/doc/libs/1_44_0/doc/html/boost_asio/reference/ip__tcp/socket.html(无法创建超链接,因为我是新来的..所以每个帖子只有1个hyperling)我可以看到该套接字类并不完全是线程安全的..

所以有2个问题: 1. 根据我刚刚编写的设计,我是否需要为所有套接字提供 1 个 io_service(意味着使其成为静态类成员),还是应该为每个套接字提供一个? 2. 如何使其线程安全?我应该将它放在“线程安全环境”中,这意味着创建一个具有互斥体和不允许您同时发送和接收的内容的新套接字类,还是您有其他建议? 3.也许我应该进行异步设计? (ofc每个套接字将有一个不同的线程,但发送和接收将在同一个线程上?)

只是为了澄清:我正在做一个连接到很多服务器的 TCP 客户端。


您需要首先决定要使用哪种套接字通信方式:

  1. 同步 - 意味着所有低级操作都是阻塞的,通常您需要一个线程用于接受,然后需要线程(读取线程或 io_service)来处理每个客户端。

  2. 异步 - 意味着所有低级操作都是非阻塞的,在这里你只需要一个线程(io_service),并且你需要能够在某些事情发生时处理回调(即接受、部分写入、读取结果等) .)

方法 1 的优点是它比 2 更容易编码(??),但是我发现 2 最灵活,事实上,使用 2,默认情况下您有一个单线程应用程序(内部事件回调是在一个独立的线程到主调度线程),当然2的缺点是你的处理延迟会影响下一个读/写操作...当然你可以使用方法2创建多线程应用程序,但反之则不然(即单线程 1) - 因此灵活性......

所以,从根本上来说,这一切都取决于风格的选择......

EDIT:更新了新信息,这很长,我懒得写代码,boost 文档中有很多内容,我将简单地描述一下正在发生的事情,以便您受益......

[主线] - 声明 io_service 的实例 - 对于您要连接的每个服务器(我假设此信息在开始时可用),创建一个类(例如ServerConnection),并在此类中,使用上面相同的 io_service 实例创建一个 tcp::socket,并在构造函数本身中调用async_connect,注意:此调用是调度连接请求,而不是真正的连接操作(这要等到稍后才会发生) - 一旦所有ServerConnection对象(以及它们各自排队的 async_connects),调用run()在 io_service 实例上。现在主线程被阻塞,无法在 io_service 队列中调度事件。

[asio线程] io_service默认有一个调用预定事件的线程,你无法控制这个线程,要实现“多线程”程序,你可以增加io_service使用的线程数,但是对于当坚持使用它的那一刻,它会让你的生活变得简单......

asio 将根据计划列表中准备好的事件来调用 ServerConnection 类中的方法。您排队的第一个事件(在调用 run() 之前)是async_connect,现在 asio 会在与服务器建立连接时回调您,通常,您将实现一个handle_connect将被调用的方法(您将该方法传递给async_connect称呼)。在handle_connect,您所要做的就是安排下一个请求 - 在这种情况下,您想要读取一些数据(可能来自此套接字),因此您调用async_read_some并传入一个函数,当有数据时通知。一旦完成,主 asio 调度线程将继续调度其他准备好的事件(这可能是其他连接请求,甚至是async_read_some您添加的请求)。

假设您被调用是因为其中一个服务器套接字上有一些数据,这些数据通过您的处理程序传递给您async_read_some- 然后您可以处理这些数据,按照需要进行操作,但是这是最重要的一点 - 完成后,安排下一个async_read_some,这样 asio 将在可用时提供更多数据。非常重要的注意事项:如果您不再安排任何请求(即退出处理程序而不排队),那么 io_service 将耗尽要分派的事件,并且 run() (您在主线程中调用)将结束。

现在,至于写作,这有点棘手。如果您的所有写入都是作为读取调用(即在 asio 线程中)处理数据的一部分完成的,那么您无需担心锁定(除非您的 io_service 有多个线程),否则在您的 write 方法中,将数据附加到缓冲区,并安排async_write_some请求(使用 write_handler,当缓冲区被部分或完全写入时将被调用)。当 asio 处理此请求时,一旦数据写入,它将调用您的处理程序,并且您可以选择调用async_write_some再次,如果缓冲区中还有更多数据,或者没有数据,则不必费心安排写入。此时,我将提到一种技术,考虑双缓冲 - 我将就此保留。如果您在 io_service 之外有一个完全不同的线程并且您想要写入,则必须调用io_service::post方法并传入一个要执行的方法(在您的ServerConnection类)以及数据,io_service 将在可能的情况下调用此方法,并且在该方法中,您可以缓冲数据并可选择调用async_write_some如果当前正在写入未进行中.

现在有一件非常重要的事情你必须小心,你绝对不能安排 async_read_some or async_write_some如果有已经有一项正在进行中,也就是说,假设您打电话给async_read_some在套接字上,在 asio 调用此事件之前,您不得安排另一个事件async_read_some,否则你的缓冲区中将会有很多垃圾!

一个好的起点是您在 boost 文档中找到的 asio 聊天服务器/客户端,它显示了如何使用 async_xxx 方法。请记住这一点,所有 async_xxx 调用都会立即返回(在几十微秒内),因此没有blocking操作,这一切都是异步发生的。http://www.boost.org/doc/libs/1_39_0/doc/html/boost_asio/example/chat/chat_client.cpp http://www.boost.org/doc/libs/1_39_0/doc/html/boost_asio/example/chat/chat_client.cpp,就是我提到的例子。

现在,如果您发现这种机制的性能太慢并且您想要线程化,您所需要做的就是增加主 io_service 可用的线程数量,并在 ServerConnection 中的读/写方法中实现适当的锁定你就完成了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 boost 套接字,我只需要一个 io_service 吗? 的相关文章

  • WPF DataGrid 多选

    我读过几篇关于这个主题的文章 但很多都是来自 VS 或框架的早期版本 我想做的是从 dataGrid 中选择多行并将这些行返回到绑定的可观察集合中 我尝试创建一个属性 类型 并将其添加到可观察集合中 它适用于单个记录 但代码永远不会触发多个
  • 调用 McAfee 病毒扫描引擎

    我收到客户的请求 要求使用他们服务器上的 McAfee 病毒扫描将病毒扫描集成到应用程序中 我做了一些调查 发现 McScan32 dll 是主要的扫描引擎 它导出各种看起来有用的函数 我还发现提到了 McAfee Scan Engine
  • 没有特殊字符的密码验证器

    我是 RegEx 的新手 已经进行了大量搜索 但没有找到任何具体内容 我正在编写一个验证密码字符串的正则表达式 可接受的字符串必须至少具有 4 种字符类型中的 3 种 数字 小写字母 大写字母 特殊字符 我对包含有一个想法 也就是说 如果这
  • 通过引用传递 [C++]、[Qt]

    我写了这样的东西 class Storage public Storage QString key const int value const void add item QString int private QMap
  • 机器Epsilon精度差异

    我正在尝试计算 C 中双精度数和浮点数的机器 epsilon 值 作为学校作业的一部分 我在 Windows 7 64 位中使用 Cygwin 代码如下 include
  • 随着时间的推移,添加到 List 变得非常慢

    我正在解析一个大约有 1000 行的 html 表 我从一个字符串中添加 10 个字符串 td 每行到一个list td
  • 如何连接重叠的圆圈?

    我想在视觉上连接两个重叠的圆圈 以便 becomes 我已经有部分圆的方法 但现在我需要知道每个圆的重叠角度有多大 但我不知道该怎么做 有人有主意吗 Phi ArcTan Sqrt 4 R 2 d 2 d HTH Edit 对于两个不同的半
  • 如何在 C++ 中标记字符串?

    Java有一个方便的分割方法 String str The quick brown fox String results str split 在 C 中是否有一种简单的方法可以做到这一点 The 增强分词器 http www boost o
  • 无限循环与无限递归。两者都是未定义的吗?

    无副作用的无限循环是未定义的行为 看here https coliru stacked crooked com view id 24e0a58778f67cd4举个例子参考参数 https en cppreference com w cpp
  • 需要帮助优化算法 - 两百万以下所有素数的总和

    我正在尝试做一个欧拉计划 http projecteuler net问题 我正在寻找 2 000 000 以下所有素数的总和 这就是我所拥有的 int main int argc char argv unsigned long int su
  • 方程“a + bx = c + dy”的积分解

    在等式中a bx c dy 所有变量都是整数 a b c and d是已知的 我如何找到整体解决方案x and y 如果我的想法是正确的 将会有无限多个解 由最小公倍数分隔b and d 但我只需要一个解决方案 我可以计算其余的 这是一个例
  • C# 列表通用扩展方法与非通用扩展方法

    这是一个简单的问题 我希望 集合类中有通用和非通用方法 例如List
  • 如何获取 EF 中与组合(键/值)列表匹配的记录?

    我有一个数据库表 其中包含每个用户 年份组合的记录 如何使用 EF 和用户 ID 年份组合列表从数据库获取数据 组合示例 UserId Year 1 2015 1 2016 1 2018 12 2016 12 2019 3 2015 91
  • WcfSvcHost 的跨域异常

    对于另一个跨域问题 我深表歉意 我一整天都在与这个问题作斗争 现在已经到了沸腾的地步 我有一个 Silverlight 应用程序项目 SLApp1 一个用于托管 Silverlight SLApp1 Web 的 Web 项目和 WCF 项目
  • 为什么使用小于 32 位的整数?

    我总是喜欢使用最小尺寸的变量 这样效果就很好 但是如果我使用短字节整数而不是整数 并且内存是 32 位字可寻址 这真的会给我带来好处吗 编译器是否会做一些事情来增强内存使用 对于局部变量 它可能没有多大意义 但是在具有数千甚至数百万项的结构
  • 有没有办法让 doxygen 自动处理未记录的 C 代码?

    通常它会忽略未记录的 C 文件 但我想测试 Callgraph 功能 例如 您知道在不更改 C 文件的情况下解决此问题的方法吗 设置变量EXTRACT ALL YES在你的 Doxyfile 中
  • 在 WPF 中使用 ReactiveUI 提供长时间运行命令反馈的正确方法

    我有一个 C WPF NET 4 5 应用程序 用户将用它来打开某些文件 然后 应用程序将经历很多动作 读取文件 通过许多插件和解析器传递它 这些文件可能相当大 gt 100MB 因此这可能需要一段时间 我想让用户了解 UI 中发生的情况
  • C++ 中的参考文献

    我偶尔会在 StackOverflow 上看到代码 询问一些涉及函数的重载歧义 例如 void foo int param 我的问题是 为什么会出现这种情况 或者更确切地说 你什么时候会有 对参考的参考 这与普通的旧参考有何不同 我从未在现
  • Mono 应用程序在非阻塞套接字发送时冻结

    我在 debian 9 上的 mono 下运行一个服务器应用程序 大约有 1000 2000 个客户端连接 并且应用程序经常冻结 CPU 使用率达到 100 我执行 kill QUIT pid 来获取线程堆栈转储 但它总是卡在这个位置
  • 如何确定 CultureInfo 实例是否支持拉丁字符

    是否可以确定是否CultureInfo http msdn microsoft com en us library system globalization cultureinfo aspx我正在使用的实例是否基于拉丁字符集 我相信你可以使

随机推荐