协程

我们经常遇到这样一种情况:

服务器A收到客户端的请求:删除该用户的某文件;

A需要向文件服务器转发请求,因此首先要把请求保存起来;

在未来的某个时刻,文件服务器发来了响应;

A再根据响应查找到保存的请求,处理,然后向客户端回复结果:删成功了,或是文件不存在,或是你没有权限等等。

是不是有点复杂?

(这里没考虑文件服务器超时,自己加timer去,不是这里的重点)。

伪代码如下:

[cpp]  view plain copy
  1. int main()  
  2. {  
  3.   while (true)  
  4.   {  
  5.      network_loop();  
  6.      处理请求;  
  7.   }   
  8. }  
  9.   
  10.   
  11.   
  12.   
  13. void 处理删文件请求(...)  
  14. {  
  15.    保存请求;  
  16.    sendTo(文件服务器);  
  17.    回到network_loop();  
  18. }  
  19.   
  20.   
  21.   
  22.   
  23.   
  24.   
  25. void  处理文件服务器的响应(...)  
  26. {  
  27.    查找请求;  
  28.   process();  
  29.   sendTo(客户端);  
  30. }  




协程是应对这种局面的利器。
听起来似乎和线程很像,但有很大的不一样:
协程更轻量级(相当于系统调用的开销而已),协程对内核透明,协程的调度依赖于应用程序,因此是非抢占的。
而线程是操作系统调度,不受我们掌控。

另外,多个协程是在一个线程中串行执行的。

(API请查看windows核心编程的《纤程》一章,以及linux的swapcontext簇函数)



当使用协程时,上面的情况处理变成了这样:
服务器A收到客户端的请求:删除该用户的某文件;

A创建协程1,切换到协程1执行;

该协程向文件服务器转发请求,将自己的唯一标识带在请求中,不等待,立即执行SwitchToCoroutine(main),回到主协程;

在未来的某个时刻,文件服务器发来了响应,主协程根据响应中的唯一标识,找到协程1,切换到协程1执行;

协程1恢复执行,处理请求,向客户端发响应。

听起来是不是也有点复杂?看看代码吧:
[cpp]  view plain copy
  1. int main()  
  2. {  
  3.   while (true)  
  4.   {  
  5.      network_loop();  
  6.      处理请求,  
  7.     或者是根据请求创建相应的协程;  
  8.   }   
  9. }  
  10.   
  11.   
  12.   
  13.   
  14. 协程1:  
  15. void 处理删文件协程(...)  
  16. {  
  17.    将自己的唯一标识放入请求;  
  18.    sendTo(文件服务器);  
  19.    Response* rsp = SwitchToCoroutine(main);   // 回到服务器主循环;  
  20.   
  21.   
  22.    process(rsp);  
  23.    sendTo(客户端);  
  24.   // 处理至此完成,  
  25.   // 此处需要主动切换回main协程;  
  26.   // 但是可以通过封装API省掉这一步骤  
  27. }  
  28.   
  29.   
  30.   
  31.   
  32.   
  33.   
  34. void  处理文件服务器的响应(Response* rsp)  
  35. {  
  36.    Coroutine* pCrt = find_coroutine_by_id();  
  37.       
  38.    SwitchToCoroutine(pCrt,  rsp); // 切换到协程1做处理。  
  39.    
  40. }  


是不是要简单的一些?最重要的是,删文件请求的处理,显得一气呵成,代码更加易读。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值