启动一个线程,并取出其中的一个变量,不使用future/promise时,代码大致如下:
#include <iostream>
using namespace std;
// 对同一变量进行操作,加锁
std::mutex mu;
// 子线程先设置 x,加信号量
std::condition_variable cond;
void factorial(int N) {
int res = 1;
for (int i = N; i > 1; i -- )
res *= i;
cout << "Result is: " << res << endl;
}
// unlock
// uncondition
int main() {
int x;
std::thread t1(factorial, 4, std::ref(x));
t1.join();
return 0;
}
代码逻辑简单时还好说,要是逻辑复杂再加上几层回调,代码可读性很低,这时候就轮到future/promise上场了
启动一个线程,并取出其中的一个变量,使用future/promise实现的大致代码如下:
#include <iostream>
#include <future>
using namespace std;
int factorial(int& N) {
int res = 1;
for (int i = N; i > 1; i -- )
res *= i;
cout << "Result is: " << res << endl;
return res;
}
int main() {
int x;
// future object 表示我们可以在未来获取某个东西
// std::async function may or may not create another thread,
// which control by another parameter: std::launch::defeered (same thread),
// std::launch::async (new thread)
std::future<int> fu = std::async(factorial, std::ref(x));
x = fu.get(); // get只能使用一次
return 0;
}
从父线程向子线程传递参数,并且该参数在未来产生
#include <iostream>
#include <future>
using namespace std;
int factorial(std::function<int>& f) {
int res = 1;
int N = f.get();
for (int i = N; i > 1; i -- )
res *= i;
cout << "Result is: " << res << endl;
return res;
}
int main() {
int x;
std::promise<int> p;
std::future<int> f = p.get_future();
// tell child thread that a value will be sent in the future
std::future<int> fu = std::async(std::launch::async, factorial, std::ref(f));
// do something else
std::this_thread::sleep_for(chrono::milliseconds(20));
// p.set_exception(std::make_except_ptr(std::runtime_error("To err is human")));
p.set_value(4);
x = fu.get(); // get 只能使用一次
return 0;
}
开十个线程的情况,可使用shared_future
#include <iostream>
#include <future>
using namespace std;
int factorial(std::shared_function<int> f) {
int res = 1;
int N = f.get();
for (int i = N; i > 1; i -- )
res *= i;
cout << "Result is: " << res << endl;
return res;
}
int main() {
int x;
std::promise<int> p;
std::future<int> f = p.get_future();
std::shared_future<int> sf = f.share();
// tell child thread that a value will be sent in the future
std::future<int> fu = std::async(std::launch::async, factorial, sf);
std::future<int> fu1 = std::async(std::launch::async, factorial, sf);
std::future<int> fu2 = std::async(std::launch::async, factorial, sf);
// 10 threads...
// do something else
std::this_thread::sleep_for(chrono::milliseconds(20));
// p.set_exception(std::make_except_ptr(std::runtime_error("To err is human")));
p.set_value(4);
x = fu.get(); // get 只能使用一次
return 0;
}