C++ 各编译器对协程支持情况(时间点 2018.08 )

N4760

N4760 是 C++标准中对协程支持的最新提案。 内容为:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/n4760.pdf

目前已经有不少编译器对它做了支持:

目前最主要的问题是 GCC 尚未开始对其做支持 : https://gcc.gnu.org/projects/cxx-status.html#tses

使用该提案的例子展示

Boost Asio 中有例子:

https://www.boost.org/doc/libs/1_68_0/doc/html/boost_asio/example/cpp17/coroutines_ts/echo_server.cpp

下面摘至以上链接部分代码:

awaitable<void> listener()
{
  auto executor = co_await this_coro::executor();
  auto token = co_await this_coro::token();

  tcp::acceptor acceptor(executor.context(), {tcp::v4(), 55555});
  for (;;)
  {
    tcp::socket socket = co_await acceptor.async_accept(token);
    co_spawn(executor,
        [socket = std::move(socket)]() mutable
        {
          return echo(std::move(socket));
        },
        detached);
  }
}

int main()
{
  try
  {
    boost::asio::io_context io_context(1);

    boost::asio::signal_set signals(io_context, SIGINT, SIGTERM);
    signals.async_wait([&](auto, auto){ io_context.stop(); });

    co_spawn(io_context, listener, detached);

    io_context.run();
  }
  catch (std::exception& e)
  {
    std::printf("Exception: %s\n", e.what());
  }
}

可以看到:

  • co_spawn 创建 1 个新协程
  • co_await 设置协程可主动让出 CPU 片的代码点

C++ 标准需要支持协程的重要性

引用下微软团队的话吧:

下面内容摘至 :https://blogs.msdn.microsoft.com/vcblog/2017/02/02/using-ibuv-with-c-resumable-functions/

Problem Space

Waiting for disks or data over a network is inherently slow and we have all learned (or been told) by now that writing software that blocks is bad, right? For client side programs, doing I/O or blocking on the UI thread is a great way to create a poor user experience as the app glitches or appears to hang. For server side programs, new requests can usually just create a new thread if all others are blocked, but that can cause inefficient resource usage as threads are often not a cheap resource.

However, it is still remarkably difficult to write code that is efficient and truly asynchronous. Different platforms provide different mechanisms and APIs for doing asynchronous I/O. Many APIs don’t have any asynchronous equivalent at all. Often, the solution is to make the call from a worker thread, which calls a blocking API, and then return the result back to the main thread. This can be difficult as well and requires using synchronization mechanisms to avoid concurrency problems. There are libraries that provide abstractions over these disparate mechanisms, however. Examples of this include Boost ASIO, the C++ Rest SDK, and libuv. Boost ASIO and the Rest SDK are C++ libraries and libuv is a C library. They have some overlap between them but each has its own strengths as well.

上面的文字大致说了 2 个问题:

  • 阻塞操作会使线程挂起,只能通过开新线程来维持程序继续工作。而多开线程是效率低下的
  • 虽然有些产品提供了异步 I/O ,但更多的 API 无法异步操作。典型例子如 mysql client api 等。只能以问题1中描述的方法去使用。

因此 C++ 标准引入协程是有重大意义的:

  • 并发编程模式简化
  • 可以预见,基于协程的 mysql 库等,就会出现
  • 后端 C++ 程序对 CPU 利用率上会做的更好

等等

以上

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fananchong2

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值