future.cpp

#include <chrono>
#include <iostream>
#include <future>
#include <thread>

std::string call_back(std::string name)
{
    std::cout << "call_back run start " << "thread_name: " << name << " thread_id: " << std::this_thread::get_id()
              << std::endl;
    std::chrono::seconds time(5);
    std::this_thread::sleep_for(time);
    std::cout << "call_back run end" << std::endl;
    return name;
}

int main()
{
    /*
        std::launch::async     开启一个新线程进行异步任务
        std::launch::deferred  延迟回调,在当前线程中执行任务
        默认情况:
            std::launch::async | std::launch::deferred 取决于系统调度,如果系统资源不紧张就会使用async,紧张情况下则使用当前调用get的线程进行任务的处理

        std::thread             会有创建线程失败的情况,可能导致程序异常退出
    */

    std::cout << "main thread_id: " << std::this_thread::get_id() << std::endl;
    auto a = std::async(std::launch::async, call_back, "async");
    auto b = std::async(std::launch::deferred, call_back, "deferred");

    std::string result = a.get();
    std::cout << "a result: " << result << std::endl;
    result = b.get();
    std::cout << "b result: " << result << std::endl;

    return 0;
}

packaged_task.cpp

#include <iostream>
#include <future>
#include <functional>
#include <thread>
#include <cmath>

int f(int a, int b)
{
    return std::pow(a, b);
}

void task_lambda()
{
    std::packaged_task<int(int, int)> task(
            [](int a, int b)
            {
                return std::pow(a, b);
            });

    std::future<int> result = task.get_future();
    task(2, 9);

    std::cout << "task_lambda: " << result.get() << std::endl;
}

void task_bind()
{
    std::packaged_task<int()> task(std::bind(f, 2, 11));
    std::future<int> result = task.get_future();
    task();

    std::cout << "task_bind: " << result.get() << std::endl;
}

void task_thread()
{
    std::packaged_task<int(int, int)> task(f);
    std::future<int> result = task.get_future();

    std::thread task_td(std::move(task), 2, 10);
    task_td.join();

    std::cout << "task_thread: " << result.get() << std::endl;
}

int main()
{
    /*
        std::packaged_task  是一个类模板,用来包装任何可调用目标(lambda/bind/其他函数对象), 使得异步能调用它, 返回值或异常可通过future对象进行获取
    */
    task_lambda();
    task_bind();
    task_thread();

    return 0;
}

promise.cpp

#include <vector>
#include <thread>
#include <future>
#include <iostream>
#include <chrono>
#include <numeric>

void accumulate(std::vector<int>::iterator first, std::vector<int>::iterator last, std::promise<int> accmulate_promise)
{
    int sum = std::accumulate(first, last, 0);
    accmulate_promise.set_value(sum);
}

void do_work(std::promise<void> barrier)
{
    std::this_thread::sleep_for(std::chrono::seconds(1));
    barrier.set_value();
}

int main()
{
    // 使用promise在线程间传递结果
    std::vector<int> numbers = {1, 2, 3, 4, 5, 6, 7};
    std::promise<int> accumulate_promise;
    std::future<int> accumulate_future = accumulate_promise.get_future();
    std::thread work_thread(accumulate, numbers.begin(), numbers.end(), std::move(accumulate_promise));

    // 等待线程执行完结果
    std::cout << "result: " << accumulate_future.get() << std::endl;
    work_thread.join();

    // 用promise<void>在线程间对状态发送信号
    std::promise<void> barrier;
    std::future<void> barrier_future = barrier.get_future();
    std::thread new_work_thread(do_work, std::move(barrier));
    barrier_future.wait();
    new_work_thread.join();
    return 0;
}

atomic.cpp

#include <atomic>
#include <thread>
#include <mutex>
#include <iostream>

#if one
int g_count = 0;

void calc()
{
    for (int i = 0; i < 100000; i++)
        g_count += i;
}

int main()
{
    std::thread t(calc);
    std::thread tt(calc);
    t.join();
    tt.join();
    // 两条线程进行操作,结果未知
    std::cout << "g_count: " << g_count << std::endl;
    return 0;
}
#endif

#if two
std::mutex g_mutex;
int g_count = 0;

void calc()
{
    for (int i = 0; i < 100000; i++)
    {
        g_mutex.lock();
        g_count++;
        g_mutex.unlock();
    }
}

int main()
{
    std::thread t(calc);
    std::thread tt(calc);
    t.join();
    tt.join();

    // 使用锁进行操作, 结果正确,但是效率不高
    std::cout << "g_count: " << g_count << std::endl;
    return 0;
}
#endif

std::atomic<int> g_count;

void calc()
{
    for (int i = 0; i < 100000; i++)
        g_count++;
}

int main()
{
    std::thread t(calc);
    std::thread tt(calc);
    t.join();
    tt.join();

    // 使用原子操作, 结果正确,效率比加锁高
    std::cout << "g_count: " << g_count << std::endl;
    return 0;
}