我有一些代码示例。我将launch::async
传递给async
,所以我希望lambda函数将立即被调用,但不会被调用。
#include <iostream>
#include <future>
#include <thread>
#include <vector>
#include <chrono>
#include <string>
using namespace std;
mutex m;
void print(string s)
{
lock_guard<mutex> l(m);
cout << s << endl;
}
int main() {
print("main thread1");
std::future<int> f = std::async(launch::async, [](){
print("async");
return 1;
});
print("main thread2");
int i = f.get();
print("main thread3");
return 0;
}
我期望的结果如下:
main thread1 async main thread2 main thread3
但是实际输出看起来像这样:
main thread1 main thread2 async main thread3
您能解释为什么只有在调用Future的get()
时才调用lambda吗?
如果我将sleep_for
放在main thread2
之前,那么输出就是我期望的结果。
答案 0 :(得分:4)
创建新线程后,将立即返回对create or replace view max_per_week as
with mx as (
select id, BOOKID, greatest(SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY) max_week from tab)
select BOOKID "BookID" , max(max_week) "MaxWeek"
from mx
group by BOOKID
;
var largestNumber = context.max_per_week.Where(s => s.BookID == "B200")
.Select(s => new int[] { s.MaxWeek})
的调用。现在,您有两个单独的线程,并且这两个线程中的操作之间的唯一关联是,对async
的调用所创建的线程必须在对async
的调用返回之前完成。因此,您看到的行为与要求一致。您期望的行为也符合要求。这就是运行单独的线程的要点:它们独立运行,直到您执行一些操作来同步它们。
答案 1 :(得分:0)
您的期望表明您并不真正理解异步的含义。让我们看一下以下算法:
operation1
asynchronous operation2
operation3
在发出对operation2的异步调用之前,正在执行operation1。异步调用operation2时,将创建一个新线程,并且不等待其结束。如果operation3期望operation2已被执行,则它是代码中的错误。如果需要给定线程的结果,则需要与之同步。
答案 2 :(得分:0)
尝试一下:
#include <iostream>
#include <future>
#include <thread>
#include <vector>
#include <chrono>
#include <string>
using namespace std;
using namespace std::chrono;
mutex m;
void print(string s)
{
lock_guard<mutex> l(m);
nanoseconds ms = duration_cast< nanoseconds >(
system_clock::now().time_since_epoch()
);
cout << s << "(" << ms.count() << ")" << endl;
}
int main() {
print("main thread1");
future<int> f = async(launch::async, [](){
print("async");
return 1;
});
//this_thread::sleep_for(2s);
print("main thread2");
int i = f.get();
print("main thread3");
return 0;
}
尝试尝试睡眠功能(this_thread::sleep_for(2s);
),以了解发生了什么事。
如果您想在“主线程2”之前看到“异步”,请在print
函数调用之前设置此睡眠。
在每个平台和OS上创建线程都是一项艰巨的任务,花费很多纳秒的时间,而仅输出某些内容则要快得多。因此,您甚至可以再添加10个print
调用-它们比在新线程内打印要快。
但是代码中的f.get()
迫使系统等待结果。它就像睡眠一样工作。因此,这是在代码示例中最后打印“ main thread3”的唯一原因。
我得到的输出与此代码:
./a.out
main thread1(1534603161902827214)
main thread2(1534603161902924375)
async(1534603161902977095)
main thread3(1534603161903114658)
“主线程1”和“主线程2”之间的差为97161。 “主线程2”和“主线程3”之间的区别是190283。所有输出都在同一线程中,逐步进行。但是此f.get()
禁止最后通话。
另一点。 C ++是一种非常难懂的语言,而学究的语法可以帮助解决代码中的错误。您在此处使用using namespace std;
,但无论如何都要编写std::
名称空间。这是风格错误。