问题标签 [packaged-task]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
6329 浏览

c++ - 在 C++11 中实现一个简单的通用线程池

我想创建一个用于实验目的的线程池(以及有趣的因素)。它应该能够处理各种各样的任务(所以我可以在以后的项目中使用它)。


在我的线程池类中,我将需要某种任务队列。由于标准库std::packaged_task从 C++11 标准开始提供,我的队列看起来像std::deque<std::packaged_task<?()> > task_queue,因此客户端可以std::packaged_task通过某种公共接口函数将 s 推送到队列中(然后池中的一个线程将收到条件变量来执行它等)。


我的问题与std::packaged_task<?()>双端队列中 s 的模板参数有关。

函数签名?()应该能够处理任何类型/数量的参数,因为客户端可以执行以下操作:

std::packaged_task<int()> t(std::bind(factorial, 342)); thread_pool.add_task(t);

所以我不必处理参数的类型/数量。

但是返回值应该是什么?(因此是问号)

  • 如果我将整个线程池类设为模板类,它的一个实例将只能处理具有特定签名(如std::packaged_task<int()>)的任务。

    我希望一个线程池对象能够处理任何类型的任务。

  • 如果我继续使用std::packaged_task<void()>并且调用的函数返回一个整数或任何东西,那么这就是未定义的行为。

0 投票
1 回答
567 浏览

variadic-templates - Using std::bind to capture a parameter pack "by move"

I'm attempting to implement std::async from scratch, and have run into a hiccup with arguments of move-only type. The gist of it is, C++14 init-captures allow us to capture single variables "by move" or "by perfect forwarding", but they do not appear to let us capture parameter packs "by move" nor "by perfect forwarding", because you can't capture a parameter pack by init-capture — only by named capture.

I've found what appears to be a workaround, by using std::bind to capture the parameter pack "by move", and then using a wrapper to move the parameters out of the bind object's storage into the parameter slots of the function I really want to call. It even looks elegant, if you don't think too much about it. But I can't help thinking that there must be a better way — ideally one that doesn't rely on std::bind at all.

(Worst case, I'd like to know how much of std::bind I'd have to reimplement on my own in order to get away from it. Part of the point of this exercise is to show how things are implemented all the way down to the bottom, so having a dependency as complicated as std::bind really sucks.)

My questions are:

  • How do I make my code work, without using std::bind? (I.e., using only core language features. Generic lambdas are fair game.)

  • Is my std::bind workaround bulletproof? That is, can anybody show an example where the STL's std::async works and my Async fails?

  • Pointers to discussion and/or proposals to support parameter-pack capture in C++1z will be gratefully accepted.

Here's my code:

0 投票
2 回答
1768 浏览

c++ - 这个语法是什么意思,`类模板班级名称`

我一直在尝试更多关于 C++ 中的多线程编程,但我很难理解std::promise,所以我开始在这个网站上搜索答案,低头看,有人和我有同样的问题。但是阅读答案让我更加困惑这是答案中的代码可能是类似的实现std::packaged_task

在这段代码中,

1-这种语法是什么意思template <typename R, typename ...Args> class my_task<R(Args...)>,更具体地说,目的是<R(Args...)>什么?

2-为什么班级有前向减速?

谢谢

0 投票
0 回答
80 浏览

c++ - 当 packaged_task 包装在线程中时,C++ 未指定 future_errc 值,代码 4

正如下面的代码所示,我试图通过传入一个 packaged_task 来实现我自己的线程类。然后我等待这个 packaged_task 的未来。我希望这段代码等待 4 秒,然后我可以从未来得到 0xcdcdcdcd。

但是等待似乎立即终止了这个任务。通过编译执行这段代码,它会立即打印出来

环境是 OS X 10.11.1,

编译命令是

我不确定它是否在其他平台上重现。

提前致谢。

编辑

已解决:这是因为mythreadnow的构造函数控制了搬入的生命周期f,其引用被线程使用。但是构造函数在创建线程后立即返回,从而销毁每个局部变量,包括f,而线程仍然持有被销毁的局部变量。

更正后的代码是

其中的控制f被进一步移动到线程中。

0 投票
0 回答
72 浏览

c++ - 带有参数错误的 C++ 未来

下面是我用来尝试运行 packaged_task 的代码。但是,当我尝试编译时,我收到错误:

'std::function<_Ret(CStore &, FileDetails &)>::function(std::function<_Ret(CStore &, FileDetails &)> &&)': cannot convert argument 1 from 'long(__cdecl &)(CStore &, std::vector<FileDetails, std::allocator<_Ty>> &)' to 'std::nullptr_t'

在将第二个参数添加到 CheckIfFilesExist 之前,我已经完成了这项工作,但是一旦我添加了第二个参数,事情就开始变得不稳定。非常感谢任何见解!

而 CStore 只是一个包含一些成员变量和这个函数的基类:

0 投票
1 回答
561 浏览

c++ - 永远不要从 std::packaged_task 检索 std::future 的结果是否安全?

std::future从 a创建 a 是否安全std::packaged_task,它在单独的线程上执行,但并不总是检索其结果?

它似乎适用于 Clang / libc++:~Result()在返回的结果上被调用std::packaged_task是否get()最终被调用std::future,但由于我在 C++ 文档中找不到关于这种使用模式的任何内容,我想确保它得到官方支持。

0 投票
1 回答
222 浏览

c++ - 当从静态方法调用非静态 Attach 时,使用 std::packaged_task 对 CAsyncSocket-Detach-socket 任务进行排队会导致编译错误

我正在实现代码,因此我可以在网络连接到达时接受它们,将它们从它们的到达套接字中分离,创建一个 std::packaged_task 任务,将该任务排队在一个双端队列容器中,然后稍后在它们的任务线程中执行这些任务。Bo Qian 在 YouTube 上关于“C++ 线程 #9:packaged_task”的讲座让这一切变得简单,展示了如何做到这一点。

在我的情况下,代码无法编译,因为我的 StartDecode 是一个试图调用非静态 Attach 的静态方法。StartDecode 是一个静态方法,因为 std::bind 用于将“套接字”绑定到任务。'socket' 通常会被传入 StartDecode 方法,但为了使打包任务中的 'future' 正常工作,必须使用 std::bind 提前绑定任何传入的参数。但是一旦 StartDecode 设置为静态,对 CAsyncSocket 的 Attach(非静态)的调用会导致错误 C2352。

如何从静态 MyRxDecode::StartDecode 调用非静态 Attach 方法?有没有办法避免将套接字参数绑定到任务而不使其成为静态?

0 投票
1 回答
55 浏览

c++ - 为什么我的线程调用一个函数对象而不是将其返回值分配给我的 packaged_task 的未来对象?

我想学习如何使用 packaged_task 检索函数的返回值。

在下面的代码中,我创建了一个运行我的函数 DoTask 的线程。然后我将该函数绑定到 packaged_task 并让它等待,同时我将它绑定到 packaged_task myTask。我提取了 myTask 的未来对象。现在我取消阻止 DoTask (notify_one) 上的条件变量,让它运行完成。我在 myTask 的 future 上执行 get() 以检索 DoTask 中返回 bool 的值。

但是,DoTask 不是等待 DoTask 返回,而是输入执行“INVOKE a function object”的代码,并且 get() 永远不会被执行。

是什么让 DoTask 无法设置我期望的未来,而是调用一个函数对象?

0 投票
1 回答
131 浏览

c++ - 成员函数可以在自由函数可以使用 std::function 的任何地方使用吗?

我有一些代码(由 GitHub 上的 progschj 提供),我已经对其进行了修改以举例说明我的问题。MakeTask 将任何函数及其参数移动到 MakeTask 中,从而生成 packaged_task。执行创建的任务,然后将其未来返回给调用者。这非常巧妙,但我也希望能够使用成员函数来做到这一点。但是,如果我将 Func 放入一个结构中,MakeTask 中的 F&& 将失败,并出现代码中记录的错误。

如果我把 Func 变成一个静态的,我可以让它工作,但这会破坏我的应用程序代码的其他部分。

Edit1:我找出了 std::function 的语法并用新的错误消息修改了示例。MakeTask 的 F&& move 参数不接受我的 aFunc 作为可调用对象。

Edit2:由于 Barry 的回答,我将示例代码更改回原始帖子,因此他的回答对未来的观众有意义。

0 投票
2 回答
339 浏览

c++ - 使用c++ packaged_task构造生产者-消费者模式

我正在尝试通过 packaged_task 创建生产者-消费者模式代码如下: test_thread9_producer1并将test_thread9_producer2任务推送到队列中并test_thread9_consumer1从队列中检索任务以执行

但是,在运行时test_thread9,它会正确执行任务但以调试错误结束:已调用 abort。我不确定为什么?任何人都可以帮助我更多地了解packaged_task吗?

第二个问题:消费者正在循环运行,当两个生产者完成将所有任务推入队列并 完成执行队列中的所有任务时while(1),我想不出优雅的方式让test_thread9_consumer1退出。test_thread9_consumer1谁能给我一些建议?