Asynchronous C++; 我决定沉浸在C++的协同程序中,阅读一些文章,观看大量的视频。据说协程对于异步编程很有用。作为一个例子,它通常演示类似的例子。 让我们看看其中一个:

Asynchronous C++; 我决定沉浸在C++的协同程序中,阅读一些文章,观看大量的视频。据说协程对于异步编程很有用。作为一个例子,它通常演示类似的例子。 让我们看看其中一个:,asynchronous,future,coroutine,c++20,c++-coroutine,Asynchronous,Future,Coroutine,C++20,C++ Coroutine,假设我们要建立TCP连接并从TCP连接获取数据: int64_t tcp_reader(int64_t total) { std::array<char, 4096> buffer; tcp::connection the_connection = tcp::connect("127.0.0.1", 1337); int64_t remaining = total; for (;;) { int64_t bytes_read = the_connection.

假设我们要建立TCP连接并从TCP连接获取数据:

int64_t tcp_reader(int64_t total) {
  std::array<char, 4096> buffer;
  tcp::connection the_connection = tcp::connect("127.0.0.1", 1337);
  int64_t remaining = total;
  for (;;) {
    int64_t bytes_read = the_connection.read(buffer.data(), buffer.size()).get();
    remaining -= bytes_read;
    if (remaining <= 0 || bytes_read == 0) { return remaining); }
  }
}
int64\t tcp\u读卡器(int64\t总计){
std::数组缓冲区;
tcp::connection\u connection=tcp::connect(“127.0.0.1”,1337);
int64_t剩余=总计;
对于(;;){
int64_t bytes_read=_connection.read(buffer.data(),buffer.size()).get();
剩余-=字节\读取;

如果(剩余的)最后一个示例代码不同步。它正在阻止将来的::get()函数调用。对于协同路由,如果
read
connect
未准备好,则co_wait表达式可以恢复另一个协同路由。@Oliv,抱歉,这是无效的代码,我忘记添加std::asynccall@Oliv,我不明白重点。“如果
read
connect
未准备就绪,则
co_wait
可以恢复另一个协同路由”。在我的示例中,是“没有协同路由”",如果它们还没有准备好,在调用方,我也可以调用另一个函数或协程。好吧,这两种情况之间的区别在于如何在低级别管理执行。使用异步,您可以获得与tcp_读取器数量相同的线程,并且程序执行将受到太多cpu上下文切换的影响。但这取决于使用协同程序,您可以对tcp_读卡器和线程的生成方式有更多的控制。但要做到这一点,
read
应该是非阻塞的,或者
连接
应该是“可轮询的”有效的现代C++中的Scott Meyers OLIV建议使用STD::未来而不是STD::Trand,以避免“过度订阅和线程外”。他提出要在库实现者上转移问题。不管怎样,使用哪种方法(协同程序或非协同程序)并不重要。,将为每个tcp_读取器创建一个异步std::future。使用协同路由方法,它必须通过promise_type::get_return_对象中的std::async隐式创建。使用非协同路由方法,它必须显式创建(如在async_tcp_读取器函数中)。没有任何区别:(
// std::future instead of just int
std::future<int64_t> tcp_reader(int64_t total) {
  std::array<char, 4096> buffer;
  // tcp::connect returns std::future. Added co_await
  tcp::connection the_connection = co_await tcp::connect("127.0.0.1", 1337);
  int64_t remaining = total;
  for (;;) {
    // tcp::connect::read returns std::future. Added co_await
    int64_t bytes_read = co_await the_connection.read(buffer.data(), buffer.size()).get();
    remaining -= bytes_read;
    if (remaining <= 0 || bytes_read == 0) { return remaining); }
  }
}
int64_t tcp_reader(int64_t total) {
  std::array<char, 4096> buffer;
  // tcp::connect returns std::future. Add get();
  tcp::connection the_connection = tcp::connect("127.0.0.1", 1337).get();
  int64_t remaining = total;
  for (;;) {
    // tcp::connect::read returns std::future. Add get();
    int64_t bytes_read = the_connection.read(buffer.data(), buffer.size()).get();
    remaining -= bytes_read;
    if (remaining <= 0 || bytes_read == 0) { return remaining); }
  }
}
std::future<int64_t> async_tcp_reader(int64_t total) {
  return std::async([total]{ tcp_reader(total); });
}