我怎样才能或者可以将模板函数传递给异步?
这是代码:
//main.cpp
#include <future>
#include <vector>
#include <iostream>
#include <numeric>
int
main
()
{
std::vector<double> v(16,1);
auto r0 = std::async(std::launch::async,std::accumulate,v.begin(),v.end(),double(0.0));
std::cout << r0.get() << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
以下是错误消息:
^
a.cpp:13:88: note: candidates are:
In file included from a.cpp:1:0:
/usr/include/c++/4.8/future:1523:5: note: template std::future::type> std::async(std::launch, _Fn&&, _Args&& ...)
async(launch __policy, _Fn&& __fn, _Args&&... __args)
^
/usr/include/c++/4.8/future:1523:5: note: template argument deduction/substitution failed:
a.cpp:13:88: note: couldn't deduce template parameter ‘_Fn’
auto r0 = std::async(std::launch::async,std::accumulate,v.begin(),v.end(),double(0.0));
^
In file included from a.cpp:1:0:
/usr/include/c++/4.8/future:1543:5: note: … 我认为使用多线程处理简单和繁重的工作(例如矩阵计算)比使用单线程更好,所以我测试了以下代码:
int main()
{
constexpr int N = 100000;
std::random_device rd;
std::mt19937 mt(rd());
std::uniform_real_distribution<double> ini(0.0, 10.0);
// single-thread
{
std::vector<int> vec(N);
for(int i = 0; i < N; ++i)
{
vec[i] = ini(mt);
}
auto start = std::chrono::system_clock::now();
for(int i = 0; i < N; ++i)
{
vec[i] = 2 * vec[i] + 3 * vec[i] - vec[i];
}
auto end = std::chrono::system_clock::now();
auto dur = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
std::cout << "single : " << dur << " ms."<< std::endl; …Run Code Online (Sandbox Code Playgroud) 我正在使用std::async创建一个线程,我希望这个新线程应该单独执行并且主线程不应该等待它。但是在这里,当我调用 std::async 时,会创建一个新线程,但主线程正在等待fun(). 我希望主线程在不等待fun()完成的情况下并行执行。我该怎么做?
#include <iostream>
#include <windows.h>
#include <future>
using namespace std;
void printid()
{
cout << "Thread id is:" << this_thread::get_id() << endl;
}
void fun(void *obj)
{
cout<<"Entry"<<endl;
printid();
Sleep(10000);
cout<<"Exit"<<endl;
}
int main()
{
cout<<"Hello"<<endl;
printid();
std::async(std::launch::async, fun, nullptr);
cout << "After call" << endl;
}
Run Code Online (Sandbox Code Playgroud)
我得到输出:
Hello
Thread id is:22832
Entry
Thread id is:13156
Exit
After call
Run Code Online (Sandbox Code Playgroud) 在描述中是std::async这样说的:
如果
std::future获取的 fromstd::async没有从引用移动或绑定到引用,则 the 的析构函数std::future将在完整表达式的末尾阻塞,直到异步操作完成,本质上使代码如下同步:Run Code Online (Sandbox Code Playgroud)std::async(std::launch::async, []{ f(); }); // temporary's dtor waits for f() std::async(std::launch::async, []{ g(); }); // does not start until f() completes(请注意,通过调用 std::async 以外的方式获得的 std::futures 的析构函数永远不会阻塞)
这个说法令人困惑,我不清楚在std::launch::deferred政策的情况下应该是什么行为。好吧,实验表明,它不会阻止,但我不知道是否规范明确地说,从未来返回std::async与std::launch::deferred政策的析构函数不会阻塞。
这打开了另一个关于默认策略的后续问题:如果未来从std::async析构函数中的块返回,std::launch::async并且在 的情况下不阻塞std::launch::deferred,那么在默认 ( std::launch::async | std::launch::deferred) 策略的情况下应该会导致非常不一致的行为。最近我在问std::asyncwith default launch policy的语义:std::async with automatic (launch::async|launch::deferred) launch policy 的语义是什么?,这个例子更让我困惑,在我们不明确知道策略的平台选择的情况下,模式的适用性是非常值得怀疑的。
更新:我发现标准P0701r1的提案并没有完全回答我的问题,但如果该提案被接受,它将解决阻塞/非阻塞析构函数的歧义。
我注意到很多已经为C++ 11更新过的经典C++参考资料源,例如cplusplus.com和Josuttis标准库参考书,似乎根本没有涵盖/有任何文档.在C++ 11并发标准库的功能,如std::thread,std::atomic,和std::async.
这些并发功能是否比标准库的其他部分"更不标准"?或者文档是否缺乏其他原因?
我编写了以下代码来测试在Ubuntu std::async()上void使用GCC 4.8.2 返回的函数.
#include <future>
#include <iostream>
void functionTBC()
{
std::cerr << "Print here\n";
}
int main(void)
{
#ifdef USE_ASYNC
auto i = std::async(std::launch::async, functionTBC);
#else
auto i = std::async(std::launch::deferred, functionTBC);
#endif
//i.get();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果i.get();取消注释,则消息"Print here"始终存在; 但是,如果i.get();被注释掉,则"Print here"存在且仅当USE_ASYNC定义时(即,std::launch::async始终导致std::launch::deferred从未打印出消息).
这是保证的行为吗?确保异步调用返回void执行的正确方法是什么?
考虑以下我试图启动 10000 个线程的两个代码片段:
片段 1
std::array<std::future<void>, 10000> furArr_;
try
{
size_t index = 0;
for (auto & fut : furArr_)
{
std::cout << "Created thread # " << index++ << std::endl;
fut = std::async(std::launch::async, fun);
}
}
catch (std::system_error & ex)
{
std::string str = ex.what();
std::cout << "Caught : " << str.c_str() << std::endl;
}
// I will call get afterwards, still 10000 threads should be active by now assuming "fun" is time consuming
Run Code Online (Sandbox Code Playgroud)
片段 2
std::array<std::thread, 10000> threadArr; …Run Code Online (Sandbox Code Playgroud) 似乎通过std::async共享未来生命周期执行的函数的参数:
#include <iostream>
#include <future>
#include <thread>
struct S
{
S() {
std::cout << "S() " << (uintptr_t)this << std::endl;
}
S(S&& s) {
std::cout << "S(&&) " << (uintptr_t)this << std::endl;
}
S(const S& s) = delete;
~S() {
std::cout << "~S() " << (uintptr_t)this << std::endl;
}
};
int main()
{
{
std::cout << "enter scope" << std::endl;
auto func = [](S&& s) {
std::cout << "func " << (uintptr_t)&s << std::endl;
auto x = S(); …Run Code Online (Sandbox Code Playgroud) I recently started adding async support to a library I'm working on, but I hit a slight problem. I started off with something like this (full context later):
return executeRequest<int>(false, d, &callback, false);
Run Code Online (Sandbox Code Playgroud)
That was before adding async support. I attempted to change it to:
return std::async(std::launch::async, &X::executeRequest<int>, this, false, d, &callback, false);
Run Code Online (Sandbox Code Playgroud)
But it failed to compile.
MCVE:
return executeRequest<int>(false, d, &callback, false);
Run Code Online (Sandbox Code Playgroud)
And it fails with:
In file included from main.cpp:2:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/5.5.0/../../../../include/c++/5.5.0/future:38:
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.5.0/../../../../include/c++/5.5.0/functional:1505:56: error: …Run Code Online (Sandbox Code Playgroud) 我试图了解async与使用线程到底有什么不同。在概念层面上,我认为多线程根据定义是异步的,因为您正在线程之间进行 I/O 等上下文切换。
但似乎即使对于单线程应用程序之类的实例,仅添加线程也与使用async. 例如:
#include <iostream> // std::cout
#include <future> // std::async, std::future
// a non-optimized way of checking for prime numbers:
bool is_prime (int x) {
std::cout << "Calculating. Please, wait...\n";
for (int i=2; i<x; ++i) if (x%i==0) return false;
return true;
}
int main ()
{
// call is_prime(313222313) asynchronously:
std::future<bool> fut = std::async (is_prime,313222313);
std::cout << "Checking whether 313222313 is prime.\n";
// ...
bool ret = fut.get(); // waits for is_prime to …Run Code Online (Sandbox Code Playgroud)