小工具知识网

当前位置: 首页 > 行业知识 > 2403C++,C++11玩转无栈协程

行业知识

2403C++,C++11玩转无栈协程

2026-10-31 10:15:48 来源:互联网转载

原���

()

C++11里也能玩无栈协程了?

答案是:可以!

事实上异网在很早时,C++11里就可用无栈协程写异步代码了,只不过用起来不太方便,来看看C++11里怎么用异网无栈协程写一个回音服务器的吧.

()
#包含 #包含 #包含 #包含 用 异网::异步写;用 异网::缓冲;用 异网::ip::传控;用 异网::错误码;用 大小型;构 会话:异网::协程{  共针套接字_;  共针缓冲_;  会话(共针 套接字)    : 套接字_(套接字),      缓冲_(新 向量(1024))  {  }  空 符号()(错误码 ec = 错误码(), 大小型 n = 0){    如 (!ec) 再入 (本)    {        对 (;;)        {            产生 套接字_->异步读些(缓冲(*缓冲_), *本);             产生 异步写(*套接字_, 缓冲(*缓冲_, n), *本);         }    }  }};构 服务器 : 异网::协程{  异网::io服务& io服务_;  共针 受者_;  共针 套接字_;  服务器(异网::io服务& io服务)    : io服务_(io服务),      受者_(新 传控::受者(io服务, 传控::端点(传控::v4(), 54321)))  {  }  空 符号()(错误码 ec = 错误码()){    再入 (本)    {        对 (;;)        {            套接字_.重置(新 传控::套接字(io服务_));            产生 受者_->异步接受(*套接字_, *本);            io服务_.提交(会话(套接字_));        }    }  }};#包含 整 主(){  异网::io服务 io服务;  io服务.提交(服务器(io服务));  io服务.跑();}

先看回声会话部分的代码:

  空 符号()(错误码 ec = 错误码(), 大小型 n = 0){    如 (!ec) 再入 (本)    {        对 (;;)        {            产生 套接字_->异步读些(缓冲(*缓冲_), *本);             产生 异步写(*套接字_, 缓冲(*缓冲_, n), *本);         }    }  }//其中对 (;;){    产生 套接字_->异步读些(缓冲(*缓冲_), *本);     产生 异步写(*套接字_, 缓冲(*缓冲_, n), *本); } 

和C++20的协程代码是不是很像:

对 (;;){    协待 套接字_->异步读些(缓冲(*缓冲_), 异网::用可等待);     协待 异步写(*套接字_, 缓冲(*缓冲_, n), 异网::用可等待); } 

所以C++11里面也是可通过协程来写异步代码的.

但是异网的无栈协程实现比较简陋,使用起来有不少约束.首先要把用无栈协程的文件用两个头文件包装起来,因为内部是宏实现的,编译完之后需要解定义.

#包含 #包含 

第二个不便之处是不自由,使用协程的对象要从异网::协程继承,然后定义符号,注意该符号是怎么写的:

  空 符号()(错误码 ec = 错误码(), 大小型 n = 0){    如 (!ec) 再入 (本)    {        对 (;;)        {            产生 套接字_->异步读些(缓冲(*缓冲_), *本);             产生 异步写(*套接字_, 缓冲(*缓冲_, n), *本);         }    }  }

相信你第一次看到该代码时会很懵,这是个啥意思,再入是什么鬼,看不懂该代码.不要着急,听我来给你解惑该符号.

参数是错误码和传输大小,最开始时是默认的,为何这两个参数呢?注意函数中的再入(本),它表明当前该函数是可重入的,则何时会重入呢?

每次产生返回时就重入了,产生之后ec和大小就是新的了.比如产生 套接字_->异步读些(缓冲(*缓冲_),*本);

返回后,就可得到错误码和读到的大小了,所以完整写法应该是:

  空 符号()(错误码 ec = 错误码(), 大小型 n = 0){    如 (!ec) 再入 (本)    {        对 (;;)        {            产生 套接字_->异步读些(缓冲(*缓冲_), *本);            //协程重入            如(ec){                输出                输出    再入 (本)    {        对 (;;)        {            套接字_.重置(新 传控::套接字(io服务_));            产生 受者_-异步接受(*套接字_, *本);            io服务_.提交(会话(套接字_));        }    }  }  如 (!ec)  {    再入 (本)    {      干      {        套接字_.重置(新 传控::套接字(受者_-取执行器()));        产生 受者_-异步接受(*套接字_, *本);        分叉 服务器(*本)();        //`分叉`之后父子协程都会往下执行到此      } 当 (是父());      产生 套接字_-异步读些(缓冲(*缓冲_), *本);       产生 异步写(*套接字_, 缓冲(*缓冲_, n), *本);     }  }}

上一篇:轻松下载应用宝,详细步骤教程来啦!

下一篇:服务器时间怎么显示的准?