C语言实现协程(三)

目录

回顾

协程常用于IO密集型,但是目前我们仅仅是实现协程的切换与调度,并没有实战检验我们的协程库。接下来我们就用我们自己实现的协程库,实现一个非阻塞的socket服务器。

实现思路

我们已经实现了协程的切换恢复等功能。
现在我们要实现的是,当协程一个IO没有数据时我们不等待,而切换到下一个IO进行处理。
如果做一个比喻的话,大概就是像上学的时候老师一个一个听学生背课文。学生一个一个排好队,第一个同学上来,老师询问会背了吗?会,那么就背诵;不会,到旁边去准备,然后继续下一个同学询问是否背诵,接着又会询问之前的同学是否会背诵。
这里的主循环就是不断接收同学并询问是否已经会背诵,而同学背诵的过程就是协程执行的过程,可以看到同时只能有一个同学在背诵。
这里的同学可以理解成同学,而老师就是主逻辑负责不断询问各个IO是否准备好,而不会背诵就是未准备好,就需要切换IO,而前面拿起课本走过来的动作就不需要做了,相当于保存了执行状态。

思路图

![思路图](https://img-blog.csdn.net/20180111124425736?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGlhb2JpbmcxOTk0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
### 实现 需要实现两个函数: 一、主循环接收连接并轮询连接的请求 主循环不断accept检测是否有新的连接,并不断恢复旧的协程。 ``` void accept_conn(int sock_fd, schedule *s, int corourine_ids[], coroutine_func handle) { int connfd = 0; while(1) { connfd = accept(sock_fd,(struct sockaddr*)NULL,NULL); if(connfd > 0) { int args[] = {sock_fd, connfd}; int id = coroutine_create(s, handle, (void *)args); int i=0; for(i=0; i

HOST = ‘localhost’ # The remote host
PORT = 8888 # The same port as used by the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
while True:
msg = raw_input(">>:")
s.sendall(msg)
data = s.recv(1024)

print('Received', repr(data))

s.close()

第二个多线程不断发送请求进行测试。

#coding: utf8
import socket
import sys
import threading
from time import ctime,sleep

threads = []

def connect_send():
count = 0
t = threading.current_thread()
tid = t.ident
res = “count:”+str(count)+"__tid:"+str(tid)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((‘127.0.0.1’, 8888))
sock.send(res)
szBuf = sock.recv(1024)
print szBuf
while(szBuf != ‘exit’):
count += 1
res = “count:”+str(count)+"__tid:"+str(tid)
sock.send(res)
szBuf = sock.recv(1024)
print(“recv:” + szBuf)
sleep(0.1)
if(count > 10):
break
sock.close()

for i in xrange(100):
t = threading.Thread(target=connect_send, args=())
threads.append(t)

if name == ‘main’:
for t in threads:
t.start()

可以看到该服务端程序能在单线程情况下响应多个连接。
![效果图](https://img-blog.csdn.net/20180111124537018?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGlhb2JpbmcxOTk0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
### 总结
这里使用我们自己实现的协程,实现了非阻塞socket的服务端,了解了协程如何处理IO问题及处理IO的过程。实际使用过程会比这个复杂,但基本原理相同。
项目代码我已经上传到github:https://github.com/xiaobing94/coroutine
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值