启动多个线程,只等待一个线程完成即可获取结果

2023-12-21

假设我有这个功能double someRandomFunction(int n)它接受一个整数并返回双精度值,但它是随机的,因为它会尝试随机的东西来得出解决方案,因此即使您使用相同的参数运行该函数,有时也可能需要 10 秒才能完成,其他则需要 40 秒才能完成。

The double someRandomFunction(int n)函数本身是黑盒函数的包装器。所以someRandomFunction需要一段时间才能完成,但我无法控制黑盒的主循环,因此我无法真正检查线程内的标志变量,因为大量计算发生在黑盒函数中。

我想启动 10 个线程来调用该函数,并且我对首先完成的第一个线程的结果感兴趣。我不在乎是哪一个,我只需要这些线程的 1 个结果。

我找到了以下代码:

  std::vector<boost::future<double>> futures;
  for (...) {
    auto fut = boost::async([i]() { return someRandomFunction(2) });
    futures.push_back(std::move(fut));
  }

  for (...) {
    auto res = boost::wait_for_any(futures.begin(), futures.end());
    std::this_thread::yield();
    std::cout << res->get() << std::endl;
  }

这是最接近我正在寻找的内容,但我仍然看不到如何让我的程序在一个线程返回解决方案的情况下终止其他线程。

我想等待一个线程完成,然后继续使用该线程的结果来继续执行我的程序(即,我不想在获得单个结果后终止我的程序,但我想使用它用于剩余的程序执行。)。

再次,我想启动 10 个线程来调用someRandomFunction然后等待一个线程先完成,获取该线程的结果并停止所有其他线程,即使它们没有完成工作。


如果提供给黑盒的数据结构具有一些明显的开始值和结束值,则使其提前完成的一种方法可能是在计算时更改最终值。如果您误解了黑匣子是如何工作的,那么它当然可能会导致各种麻烦must处理数据,但如果你相当确定,它是可行的。

main 生成 100 个外线程,每个外线程生成一个调用黑盒的内线程。内部线程接收黑盒结果并通知所有等待线程它已完成。外线程等待any内部线程完成,然后修改其自己的黑匣子的数据以欺骗其完成。

没有轮询(除了虚假的唤醒循环),也没有分离的线程。

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <vector>
#include <chrono>

// a work package for one black-box
struct data_for_back_box {
    int start_here;
    int end_here;
};

double blackbox(data_for_back_box* data) {
    // time consuming work here:
    for(auto v=data->start_here; v<data->end_here; ++v) {
        std::this_thread::sleep_for(std::chrono::milliseconds(10));
    }
    // just a debug
    if(data->end_here==0) std::cout << "I was tricked into exiting early\n";
    return data->end_here;
}

// synchronizing stuff and result
std::condition_variable cv;
std::mutex mtx;
bool done=false;
double result;

// a wrapper around the real blackbox
void inner(data_for_back_box* data) {
    double r = blackbox(data);
    if(done) return; // someone has already finished, skip this result

    // notify everyone that we're done
    std::unique_lock<std::mutex> lock(mtx);
    result = r;
    done=true;
    cv.notify_all();
}

// context setup and wait for any inner wrapper
// to signal "done"
void outer(int n) {
    data_for_back_box data{0, 100+n*n};
    std::thread work(inner, &data);
    {
        std::unique_lock<std::mutex> lock(mtx);
        while( !done ) cv.wait(lock);
    }
    // corrupt data for blackbox:
    data.end_here = 0;
    // wait for this threads blackbox to finish
    work.join();
}

int main() {
    std::vector<std::thread> ths;

    // spawn 100 worker threads
    for(int i=0; i<100; ++i) {
        ths.emplace_back(outer, i);
    }

    double saved_result;
    {
        std::unique_lock<std::mutex> lock(mtx);
        while( !done ) cv.wait(lock);
        saved_result = result;
    } // release lock

    // join all threads
    std::cout << "got result, joining:\n";
    for(auto& th : ths) {
        th.join();
    }

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

启动多个线程,只等待一个线程完成即可获取结果 的相关文章

  • 属性对象什么时候创建?

    由于属性实际上只是附加到程序集的元数据 这是否意味着属性对象仅根据请求创建 例如当您调用 GetCustomAttributes 时 或者它们是在创建对象时创建的 或者 前两个的组合 在由于 CLR 的属性扫描而创建对象时创建 从 CLR
  • 自动从 C# 代码进行调试过程并读取寄存器值

    我正在寻找一种方法来读取某个地址的 edx 注册表 就像这个问题中所问的那样 读取eax寄存器 https stackoverflow com questions 16490906 read eax register 虽然我的解决方案需要用
  • 在 Xamarin Android 中将图像从 URL 异步加载到 ImageView 中

    我有一个包含多个项目的 ListView 列表中的每个项目都应该有一个与之关联的图像 我创建了一个数组适配器来保存每个列表项并具有我希望加载的图像的 url 我正在尝试使用 Web 请求异步加载图像 并设置图像并在加载后在视图中更新它 但视
  • C++ 求二维数组每一行的最大值

    我已经设法用这个找到我的二维数组的每一行的最小值 void findLowest int A Cm int n int m int min A 0 0 for int i 0 i lt n i for int j 0 j lt m j if
  • iPhone SDK - 在后台线程中运行重复进程

    我有一个iPhone我想在其中每隔一段时间在后台执行一个方法的应用程序1第二 所以在我的主线程中 我有以下代码UIViewController viewDidLoad NSTimer timerWithTimeInterval 1 0 ta
  • SSH 主机密钥指纹与模式 C# WinSCP 不匹配

    我尝试通过 WinSCP 使用 C 连接到 FTPS 服务器 但收到此错误 SSH 主机密钥指纹 与模式不匹配 经过大量研究 我相信这与密钥的长度有关 当使用 服务器和协议信息 下的界面进行连接时 我从 WinSCP 获得的密钥是xx xx
  • 如何在我的应用程序中使用 Windows Key

    Like Windows Key E Opens a new Explorer Window And Windows Key R Displays the Run command 如何在应用程序的 KeyDown 事件中使用 Windows
  • 跨多个控件共享事件处理程序

    在我用 C 编写的 Windows 窗体应用程序中 我有一堆按钮 当用户的鼠标悬停在按钮上时 我希望按钮的边框发生变化 目前我有以下多个实例 每个按钮一个副本 private void btnStopServer MouseEnter ob
  • 如何在 WPF RichTextBox 中跟踪 TextPointer?

    我正在尝试了解 WPF RichTextBox 中的 TextPointer 类 我希望能够跟踪它们 以便我可以将信息与文本中的区域相关联 我目前正在使用一个非常简单的示例来尝试弄清楚发生了什么 在 PreviewKeyDown 事件中 我
  • C# 用数组封送结构体

    假设我有一个类似于 public struct MyStruct public float a 我想用一些自定义数组大小实例化一个这样的结构 在本例中假设为 2 然后我将其封送到字节数组中 MyStruct s new MyStruct s
  • A* 之间的差异 pA = 新 A;和 A* pA = 新 A();

    在 C 中 以下两个动态对象创建之间的确切区别是什么 A pA new A A pA new A 我做了一些测试 但似乎在这两种情况下 都调用了默认构造函数 并且仅调用了它 我正在寻找性能方面的任何差异 Thanks If A是 POD 类
  • 编译的表达式树会泄漏吗?

    根据我的理解 JIT 代码在程序运行时永远不会从内存中释放 这是否意味着重复调用 Compile 表达式树上会泄漏内存吗 这意味着仅在静态构造函数中编译表达式树或以其他方式缓存它们 这可能不那么简单 正确的 他们可能是GCed Lambda
  • 我的 strlcpy 版本

    海湾合作委员会 4 4 4 c89 我的程序做了很多字符串处理 我不想使用 strncpy 因为它不会终止 我不能使用 strlcpy 因为它不可移植 只是几个问题 我怎样才能让我的函数正常运行 以确保它完全安全稳定 单元测试 这对于生产来
  • AccessViolationException 未处理

    我正在尝试使用史蒂夫 桑德森的博客文章 http blog stevensanderson com 2010 01 28 editing a variable length list aspnet mvc 2 style 为了在我的 ASP
  • EPPlus Excel 更改单元格颜色

    我正在尝试将给定单元格的颜色设置为另一个单元格的颜色 该单元格已在模板中着色 但worksheet Cells row col Style Fill BackgroundColor似乎没有get财产 是否可以做到这一点 或者我是否必须在互联
  • 作为字符串的动态属性名称

    使用 DocumentDB 创建新文档时 我想设置属性名称动态地 目前我设置SomeProperty 像这样 await client CreateDocumentAsync dbs db colls x new SomeProperty
  • GDK3/GTK3窗口更新的精确定时

    我有一个使用 GTK 用 C 语言编写的应用程序 尽管该语言对于这个问题可能并不重要 这个应用程序有全屏gtk window与单个gtk drawing area 对于绘图区域 我已经通过注册了一个刻度回调gtk widget add ti
  • 在 ASP.NET 中将事件冒泡为父级

    我已经说过 ASP NET 中的层次结构 page user control 1 user control 2 control 3 我想要做的是 当控件 3 它可以是任何类型的控件 我一般都想这样做 让用户用它做一些触发回发的事情时 它会向
  • 窗体最大化时自动缩放子控件

    有没有办法在最大化屏幕或更改分辨率时使 Windows 窗体上的所有内容自动缩放 我发现手动缩放它是正确的 但是当切换分辨率时我每次都必须更改它 this AutoScaleDimensions new System Drawing Siz
  • 如何使用 ReactiveList 以便在添加新项目时更新 UI

    我正在创建一个带有列表的 Xamarin Forms 应用程序 itemSource 是一个reactiveList 但是 向列表添加新项目不会更新 UI 这样做的正确方法是什么 列表定义 listView new ListView var

随机推荐