Skip to content

第四章-并发操作的同步

回到目录

4.1 等待事件或等待其他条件

4.1.1 凭借条件变量等待条件成立

std::condition_variable 和 std::condition_variable_any

4.2 使用future等待一次性事件发生

C++标准程序库有两种future,分别由两个类模板实现,其声明位于标准库的头文件内:独占future(unique future,即std::future<>)和共享future(shared future,即std::shared_future<>)它们的设计参照了std::unique_ptr和std::shared_ptr。和条件变量+互斥锁差不多。

使用方式可以参考这个链接 std::promise介绍及使用

如果没有关联数据,我们应使用特化的模板std::future和std::shared_future,可以实现简单的同步功能,类似于简单的条件变量

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

void Thread_Fun1(std::promise<void> &p)
{
  std::this_thread::sleep_for(std::chrono::seconds(3));
  std::cout << "will trigger" << std::endl;
  p.set_value();
}

void Thread_Fun2(std::future<void> &f)
{
  f.get();
  std::cout << "get trigger" << std::endl;
}

int main()
{
  std::promise<void> pr1;
  std::future<void> fu1 = pr1.get_future();

  std::thread t1(Thread_Fun1, std::ref(pr1));
  std::thread t2(Thread_Fun2, std::ref(fu1));

  t1.join();
  t2.join();

  return 0;
}

4.2.1 从后台任务返回值

std::async(),它是对线程更高层次的抽象

知乎链接

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

int get_ret(int count) {
    int ret = 0;
    for (int i = 0; i < count; i++) {
        ret += i;
    }
    return ret;
}

int main()
{
    std::future<int> value = std::async(get_ret, 10);
    // std::future<int> value = std::async(std::launch::async | std::launch::deferred, get_ret, 10);
    // std::future<int> value = std::async(std::launch::async, get_ret, 10);
    // std::future<int> value = std::async(std::launch::deferred, get_ret, 10);
    std::cout << "get ret = " << value.get() << std::endl;

    return 1;
}

4.2.2 关联future实例和任务

std::packaged_task,std::packaged_task与std::future关联,可以传入函数等可调用实体 简单例子

4.2.3 创建std::promise

std::promise。见4.2章节

4.2.4 将异常保存到future中

4.2.5 多个线程一起等待

std::shared_future

4.3 限时等待

有两种超时(timeout)机制可供选用:一是迟延超时(duration-based timeout),线程根据指定的时长而继续等待(如30毫秒);二是绝对超时(absolute timeout),在某特定时间点(time point)来临之前,线程一直等待

4.3.1 时钟类

std::chrono::system_clock std::chrono::steady_clock std::chrono::high_resolution_clock

4.3.2 时长类

std::chrono::duration<>

// 延时10s
std::this_thread::sleep_for(std::chrono::seconds(10));
// 延时10ms
std::this_thread::sleep_for(std::chrono::milliseconds(10));
// 延时10us
std::this_thread::sleep_for(std::chrono::microseconds(10));
// 延时10ns
std::this_thread::sleep_for(std::chrono::nanoseconds(10));

4.3.3 时间点类

std::chrono::time_point<>

4.3.4 接受超时时长的函数

4.4 运用同步操作简化代码

TODO