You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何C++测试库libunifex会执行两次计算?相关技术疑问

关于libunifex中Sender复用导致重复执行的问题解答

问题背景

测试libunifex库时发现执行行为不符合预期,示例代码如下:

#include <unifex/sync_wait.hpp>
#include <unifex/then.hpp>
#include <unifex/when_all.hpp>
#include <unifex/single_thread_context.hpp>

#include <iostream>

int main() {
    using namespace unifex;

    single_thread_context context;
    sender auto s0 = schedule(context.get_scheduler());
    sender auto s1 = then(s0, [](){
        std::cout << "do complex computation" << std::endl;
    });
    sender auto s21 = then(s1, [](){});
    sender auto s22 = then(s1, [](){});
    sync_wait(when_all(s21, s22));
}

需求是让s1中的复杂计算仅执行一次,但实际被执行了两次,存在两个疑问:

  1. 该需求(让s1仅计算一次)是否被P2300r1文档支持?
  2. libunifex中未实现的split函数是否与该需求有关?

解答

1. P2300r1对该需求的支持情况

P2300r1定义的Sender核心语义是:每次启动(start)Sender都会完整执行其对应的工作流。你当前的代码中,when_all会分别启动s21和s22,而这两个Sender各自依赖s1,因此会分别启动s1两次,导致计算逻辑重复执行,这是符合标准语义的。

但P2300r1明确支持"共享Sender执行结果"的场景——即让一个Sender的执行结果被多个下游Sender复用,避免重复执行上游逻辑。你的需求完全符合标准文档的设计目标,只是需要使用专门的多播/共享机制来实现,而非直接复用同一个Sender实例。

2. split函数与需求的关系

是的,split函数正是解决这类问题的核心工具。它的作用是将一个普通Sender转换为可被多个下游订阅的Sender,确保上游工作流仅执行一次,执行结果被所有下游Sender复用。由于libunifex目前尚未实现split,所以你无法直接通过该函数满足需求。

临时替代实现方案

在split函数实现前,可以通过shared_future结合libunifex的Sender机制模拟类似效果,示例如下:

#include <unifex/sync_wait.hpp>
#include <unifex/then.hpp>
#include <unifex/when_all.hpp>
#include <unifex/single_thread_context.hpp>
#include <future>
#include <iostream>

int main() {
    using namespace unifex;

    single_thread_context context;
    // 先执行一次s1的逻辑,用shared_future缓存结果
    auto shared_result = sync_wait(then(schedule(context.get_scheduler()), [](){
        std::cout << "do complex computation" << std::endl;
        return 0;
    })).value();
    auto shared_fut = std::make_shared<decltype(shared_result)>(shared_result);

    // 下游Sender复用缓存的结果,无需重复执行上游逻辑
    sender auto s21 = then(schedule(context.get_scheduler()), [shared_fut](){
        // 此处可使用shared_fut中的结果
    });
    sender auto s22 = then(schedule(context.get_scheduler()), [shared_fut](){
        // 此处可使用shared_fut中的结果
    });
    sync_wait(when_all(s21, s22));
}

内容的提问来源于stack exchange,提问作者macomphy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 07:25:27