C++11 提供了线程库和同步库,可以屏蔽操作系统接口细节使用多线程了
多线程
std::thread
创建与使用
std::this_thread
当前线程
线程同步
lock_guard
互斥锁
unique_lock
+ condition_variable
条件锁
原子操作库
实现轻量免锁的多线程安全操作
https://zh.cppreference.com/w/cpp/atomic/atomic
https://zh.cppreference.com/w/cpp/atomic/atomic_flag
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| std::atomic_int ttt; void test(bool add) { for (int i = 0; i < 100000; ++i) { if (add) ++ttt; else --ttt; } printf("th exit!\n"); } int main() { ttt = 0; std::vector<std::thread> ths; for (int i = 0; i < 4; ++i) { ths.emplace_back(test, i % 2 == 0); } for (auto& th : ths) { th.join(); } std::cout << ttt << std::endl; return 0; }
|
输出为 0; 如果把头一行的 std::atomic_int 换成 int, 得到的结果偏差巨大
异步任务 future & promise
定义于 <future>
头文件
使用 future 三种方式: packaged_task, promise, async
https://zh.cppreference.com/w/cpp/thread/future
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| #include <iostream> #include <future> #include <thread>
int main() { std::packaged_task<int()> task([](){ return 7; }); std::future<int> f1 = task.get_future(); std::thread(std::move(task)).detach();
std::future<int> f2 = std::async(std::launch::async, [](){ return 8; });
std::promise<int> p; std::future<int> f3 = p.get_future(); std::thread( [&p]{ p.set_value_at_thread_exit(9); }).detach();
std::cout << "Waiting..." << std::flush; f1.wait(); f2.wait(); f3.wait(); std::cout << "Done!\nResults are: " << f1.get() << ' ' << f2.get() << ' ' << f3.get() << '\n'; }
|
std::async
最简单的异步任务使用
1 2
| std::launch::async // 运行新线程, 以异步执行任务 std::launch::deferred // 调用方线程上首次请求其结果时执行任务(惰性求值)
|
1 2 3 4
| std::future<int> f2 = std::async(std::launch::async, [](){ return 8; }); f2.wait(); int result = f2.get();
|