asio:如何将对象从一个io上下文传递到另一个io上下文

2024-01-26

我试图更好地理解 async asio 的工作原理。

我有以下代码,我在套接字上调用 async_read 来读取接下来的 10 个字节的数据。

struct SocketReader {
    void do_read_body()
    {
        asio::async_read(socket_,
            asio::buffer(msg_, 10),
            [this](asio::error_code ec, std::size_t length)
            {
                if (!ec)
                {
                    //messages_to_work_on.emplace_back(msg_); // <-- I'm trying to send this msg_ instance to another io_context
                    do_read_body(); // call again
                }
                else
                {
                    socket_.close();
                }
            });
    }
std::vector<uint8_t> msg_;
asio::tcp::socket _socket;
}

这些读取是在他自己的 std::thread 中运行的 io_context 内完成的,我在队列中收集从套接字读取的所有消息。到目前为止,一切都很好。

我还有另一个“worker”类,它只是根据队列中可用的内容执行一些工作:

struct Worker
{
    asio::io_context& io_context_;
    std::deque< std::vector<uint8_t> > queue;
    Worker(asio::io_context& io_context)
        : io_context_(io_context) {
        asio::post(io_context_, [this]() {doWork();});
    }
    void doWork() {
        if (!queue.empty())
        {
            // do some work with front()
            queue.pop_front();
        }
        asio::post(io_context_, [this]() {doWork();});
    }
};

那一个也在他自己的 io_context 中执行,在他自己的线程中运行。所以socket线程和工作线程之间存在并发。

将从套接字接收到的数据发送到工作人员类的正确方法是什么? 我想我应该能够从套接字完成处理程序调用,例如:

asio::post(worker_io_context, [this]() {worker.queue.push_back(msg_)});

这样,我至少可以确定工作队列不会同时使用。 但我不确定是否允许我从一个 io_context 发布到另一个,也不确定我是否不会以这种方式创建另一个竞争条件。 我也不太明白消息的内存应该位于哪里,尤其是从一个 io_context 到另一个 io_context 的传输“之间”。是否需要按值传递消息(因为可以在执行后处理程序之前修改 this.msg_ )?

Thanks!


我应该能够从套接字完成处理程序调用, 就像是:

asio::post(worker_io_context, [this]() {worker.queue.push_back(msg_)});

Sure.

这样,我至少可以确定工作队列不会同时使用。但我不确定是否允许我从一个 io_context 发布到另一个,

io_context不是魔法。它们基本上是协作任务队列。

并且如果我不会以这种方式创建另一个竞争条件。

我不会坐在这里并在没有看到您的代码的情况下做出裁决(无论如何我可能不想阅读所有内容),但让我重复一遍:io_context不是魔法。您可以按照您已经知道的方式对线程、任务和资源进行推理。

我也不太明白消息的内存应该位于哪里,尤其是从一个 io_context 到另一个 io_context 的传输“之间”。是否需要按值传递消息(因为可以在执行后处理程序之前修改 this.msg_ )?

是的。的确。就像是

post(worker_io_context, [this, msg=std::move(msg_)]() {worker.queue.push_back(std::move(msg)); });

如果移动并不便宜,可以选择使用引用计数的智能指针(如shared_ptr)。考虑做一下smartpointer<T const>如果您实际上在线程之间共享所有权。


淋浴想法:也许你可以不用“工人”队列。由于您正在转向反应器式异步(使用 Asio),因此您可能会专注于对任务进行排队,而不是对数据进行排队。不这样做的原因包括当您想要优先级排队、负载平衡/背压等时。[原则上所有这些都可以使用自定义执行器来实现,但在这样做之前我会坚持我所知道的。]

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

asio:如何将对象从一个io上下文传递到另一个io上下文 的相关文章

随机推荐

  • 如何检查变量是否在 Octave 中定义?

    当编写加载数据的脚本时 每次等待它加载都是浪费时间 如何检查变量是否已定义 您可以使用existOctave 中的函数来完成这项工作 它可用于检查给定名称作为变量 内置函数 文件或目录是否存在 在您的情况下 要检查变量是否存在 您可以使用如
  • C ++在for循环中初始化2个不同的迭代器[重复]

    这个问题在这里已经有答案了 可能的重复 我可以在 for 循环的初始化中声明不同类型的变量吗 https stackoverflow com questions 8644707 can i declare variables of diff
  • 如何覆盖 javascript 本机对象的内置方法

    假设我们有窗口对象的警报方法 我想用漂亮的警报框来增强它 另外 我想保存现有的警报方法 以便我们可以在应用程序结束后切换回来 类似这样的东西 但它在 Firefox 控制台中抛出错误 window prototype alert funct
  • pip 可以与 Visual Studio 中的 Python 工具一起使用吗?

    我正在与一些同学合作构建一个 python 应用程序 并希望使用 Visual Studio 智能感知的 训练轮 他们在 mac 和 linux 上使用 python 所以理想情况下我们的源代码控制存储库将仅包含 py我们编写的源文件 以及
  • 在 Tensorflow 中实现暹罗网络

    我想实现一个连体卷积神经网络 其中两个图像在卷积层中共享权重 然后在通过全连接层之前进行连接 我尝试过一种实现 但它似乎是一个 黑客 解决方案 特别是 我已将张量上的操作定义为简单的 Python 函数 并且我不确定这是否允许 这是我尝试过
  • 有没有可靠的方法从 postgres 间隔中提取年份?

    在 Postgres 中 如果我执行以下操作 select now created at from my table 我得到这样的结果 854 days 12 04 50 29658 然而 如果我这样做 select age now cre
  • 我什么时候需要下载.Net core运行时?

    From this https dotnet microsoft com download sdk链接 我们可以下载Core SDK和Runtime 据我了解 SDK 包含运行时 但在什么情况下我应该下载 Net Core Runtime
  • 如何使用 :: 让 vimomnicompletion 支持 php 类方法

    使用 vim php ctags 我可以获得相当好的 php 自动完成功能 但有一个部分确实让我困惑 让 vim 自动完成类方法 这是一个例子 完整的方法是 CVarDumper dumpAsString 如果我输入以下内容 我希望它完成
  • 这个周末用 php 吗?

    我想用 php 度过这个周末 我通过代码获取当前日期 start date date Y m d H i s time 如何根据当前日期获取当前周末 谢谢你 PHP 斯特托时间 http fr php net strtotime函数很神奇
  • 无法通过java客户端获取Hadoop作业信息

    我使用 Hadoop 1 2 1 并尝试通过 java 客户端打印作业详细信息 但它没有打印任何内容 这是我的 java 代码 Configuration configuration new Configuration configurat
  • 为服务指定 SEND(共享)意图过滤器

    我正在尝试过滤和处理意图android intent action SEND我的其中一项行动Services 我在我的AndroidManifest xml
  • TensorFlow 形状 (?,) 是什么意思?

    我得到的 TensorFlow 张量的形状为 这个答案 https stackoverflow com a 40953146 5353461说 意味着维度在图中并不固定 并且在运行调用之间可能会有所不同 什么是 意思是与尾随逗号连用吗 文档
  • 在 MATLAB 中预分配内存 à la std::vector::reserve(n)

    So reserve当您大致了解尺寸要求时 此功能非常有用 有谁知道在 MATLAB 中预分配数组的类似方法吗 我对像下面这样的黑客 但有效 方法并不真正感兴趣 x zeros 1000 1 for i 1 10000 if i gt nu
  • R 将文本文件导入为数据框列表

    我有一个很长的txt文件 组织如下 RANGE P1 H1 P3 H4 P10 H72 P14 H76 RANGE P1 H1 P10 H8 P11 H8 我想在 R 中阅读它 创建一个数据帧列表 其中 RANGE 和 界定每一项的内容 因
  • 使用元标记的 IE 10 兼容模式

    基本上我有这个网站 在所有版本的 IE 的兼容模式 IE7 下都运行得很好 我为此在 IIS 中使用了元标记 现在的问题是 IE10 其中文档模式已更改为 IE 标准 但浏览器模式并未更改为兼容 您能指导我找到解决方案吗 元标记会为您更改文
  • 多播委托 - 多个类从 iOS 中的 UI 控件接收通知

    据我了解 UITextField 等 UI 控件通过其委托通知客户端交互 事件 该委托被定义为支持所需协议的类 我经常发现自己想要在多个类中接收 UI 事件的通知 因此希望支持多播 例如 为一个 UI 控件指定多个委托 我非常确定没有任何
  • 创建基于编译器的“字典”的非静态版本,其中键是类型

    有一个非常简单的技巧可以创建一个类似字典的结构 其中键是类型 该结构就像一个Dictionary
  • 柯里化是如何工作的?

    总的来说 我对 Haskell 和 FP 很陌生 我读过许多描述柯里化是什么的文章 但我还没有找到它实际工作原理的解释 这是一个函数 a gt a gt a 如果我做 4 7 该函数取4并返回一个函数 该函数接受7并返回11 但会发生什么4
  • 设置集成测试环境

    我想在我的集成测试中使用设置环境WebApplicationFactory 默认情况下 env 设置为Development 我的网络应用程序工厂的代码如下所示 public class CustomWebApplicationFactor
  • asio:如何将对象从一个io上下文传递到另一个io上下文

    我试图更好地理解 async asio 的工作原理 我有以下代码 我在套接字上调用 async read 来读取接下来的 10 个字节的数据 struct SocketReader void do read body asio async