tonardo学习之路

异步原理

blockio.py

#阻塞io
import requests
# html = requests.get("http://www.baidu.com").text
# #1. 三次握手建立tcp连接,
# # 2. 等待服务器响应
# print(html)

#如何通过socket直接获取html
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = "www.baidu.com"
client.connect((host, 80))  #阻塞io, 意味着这个时候cpu是空闲的
client.send("GET {} HTTP/1.1\r\nHost:{}\r\nConnection:close\r\n\r\n".format("/", host).encode("utf8"))

data = b""
while 1:
    d = client.recv(1024) #阻塞直到有數據
    if d:
        data += d
    else:
        break

data = data.decode("utf8")
print(data)

 

noblockio.py

import socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.setblocking(False)
host = "www.baidu.com"

try:
    client.connect((host, 80))  #阻塞io, 意味着这个时候cpu是空闲的
except BlockingIOError as e:
    #做一些其他事
    pass

while 1:
    try:
        client.send("GET {} HTTP/1.1\r\nHost:{}\r\nConnection:close\r\n\r\n".format("/", host).encode("utf8"))
        print("send success")
        break
    except OSError as e:
        pass

data = b""
while 1:
    try:
        d = client.recv(1024) #阻塞直到有數據
    except BlockingIOError as e:
        continue
    if d:
        data += d
    else:
        break

data = data.decode("utf8")
print(data)
View Code

selector.py

import socket
from selectors import DefaultSelector, EVENT_WRITE, EVENT_READ

selector = DefaultSelector()#根据操作系统自动选择select或者epoll

class Fetcher:
    def connected(self, key):
        selector.unregister(key.fd)
        self.client.send("GET {} HTTP/1.1\r\nHost:{}\r\nConnection:close\r\n\r\n".format("/", self.host).encode("utf8"))
        selector.register(self.client.fileno(), EVENT_READ, self.readble)

    def readble(self, key):
        d = self.client.recv(1024)
        if d:
            self.data += d
        else:
            selector.unregister(key.fd)
            data = self.data.decode("utf8")
            print(data)

    def get_url(self, url):
        self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.client.setblocking(False)
        self.data = b""
        self.host = "www.baidu.com"

        try:
            self.client.connect((self.host, 80))  # 阻塞io, 意味着这个时候cpu是空闲的
        except BlockingIOError as e:
            # 做一些其他事
            pass

        selector.register(self.client.fileno(), EVENT_WRITE, self.connected)

def loop_forever():
    #事件循环
    while 1:
        ready = selector.select()
        for key, mask in ready:
            call_back = key.data
            call_back(key)

if __name__ == "__main__":
    fetcher = Fetcher()
    url = "http://www.baidu.com"
    fetcher.get_url(url)
    loop_forever()
View Code

coroutine.py

#1. 什么是协程
#1.回调过深造成代码很难维护
#2.栈撕裂造成异常无法向上抛出
#协程- 可以被暂停并切换到其他协程运行的函数
from tornado.gen import coroutine

async def yield_test():
    yield 1
    yield 2
    yield 3

async def main():
    result = await yield_test()

async def main2():
    await yield_test()

my_yield = yield_test()
for item in my_yield:
    print(item)
View Code

asynhttpclient.py

from tornado import httpclient
#
# http_client = httpclient.HTTPClient()
# try:
#     response = http_client.fetch("http://www.tornadoweb.org/en/stable/")
#     print(response.body.decode("utf8"))
# except httpclient.HTTPError as e:
#     # HTTPError is raised for non-200 responses; the response
#     # can be found in e.response.
#     print("Error: " + str(e))
# except Exception as e:
#     # Other errors are possible, such as IOError.
#     print("Error: " + str(e))
# http_client.close()
#异步方式,代码写法和同步无太大差别
async def f():
    http_client = httpclient.AsyncHTTPClient()
    try:
        response = await http_client.fetch("http://www.tornadoweb.org/en/stable/")
    except Exception as e:
        print("Error: %s" % e)
    else:
        print(response.body.decode("utf8"))

if __name__ == "__main__":
    import tornado
    io_loop = tornado.ioloop.IOLoop.current()

    #run_sync方法可以在运行完某个协程之后停止事件循环
    io_loop.run_sync(f)
View Code

 





posted @ 2020-04-23 09:52  tacyi  阅读(392)  评论(0编辑  收藏  举报