预先知道:

    1.并发:是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机(CPU)上运行,
       但任一个时刻点上只有一个程序在处理机上运行。
2.并行:是指任何时间点,有多个程序运行在多个CPU上(最多和CPU数量一致) 3.同步:是指代码调用IO操作时,必须等待IO操作完成才能返回的调用方式。 4.异步:是指代码调用IO操作时,不必等待IO操作完成就能返回的调用方式。 5.阻塞:是指调用函数的时候当前线程被挂起。 6.非阻塞:是指调用函数的时候当前线程不会被挂起,而是立即返回。

unix下的5大io类型

爬虫10-1(协程)

 

 

 

  1阻塞I式/O:系统调用不会立即返回结果,当前线程会阻塞,等到获得结果或报错时在返回(问题:如在调用send()的同时,线程将被阻塞,
在此期间,线程将无法执行任何运算或响应任何的网络请求。)   2非阻塞式I
/O:调用后立即返回结果(问题:不一定三次握手成功,recv() 会被循环调用,循环调用recv()将大幅度推高CPU 占用率),
做计算任务或者再次发起其他连接就较有优势   3I
/O复用:它的基本原理就是select/epoll这个function会不断的轮询所负责的所有socket,当某个socket有数据到达了,就通知用户进程。
(阻塞式的方法,可以监听多个socket状态)(问题:将数据从内核复制到用户空间的时间不能省)   5异步I
/O:它就像是用户进程将整个IO操作交给了他人(kernel)完成,然后他人做完后发信号通知。在此期间,用户进程不需要去检查IO操作的状态,
也不需要主动的去拷贝数据。

通过非阻塞io实现http请求:

import socket
from urllib.parse import urlparse

def get_url(url):
    #通过socket请求html
    url=urlparse(url)
    host=url.netloc
    path=url.path
    if path=="":
        path="/"
    #建立socket连接
    client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    #设置成非阻塞(抛异常:BlockingIOError: [WinError 10035] 无法立即完成一个非阻止性套接字操作。)
    client.setblocking(False)
    try:
        client.connect((host,80))
    except BlockingIOError as e:
        pass
    #向服务器发送数据(还未连接会抛异常)
    while True:
        try:
            client.send("GET {} HTTP/1.1\r\nHost:{}\r\nConnection:close\r\n\r\n".format(path, host).encode("utf8"))
            break
        except OSError as e:
            pass
    #将数据读取完
    data=b""
    while True:
        try:
            d=client.recv(1024)
        except BlockingIOError as e:
            continue
        if d:
            data+=d
        else:
            break
    #会将header信息作为返回字符串
    data=data.decode('utf8')
    print(data.split('\r\n\r\n')[1])
    client.close()

if __name__=='__main__':
    get_url('http://www.baidu.com')
View Code

相关文章:

  • 2022-03-03
  • 2021-05-16
  • 2021-04-08
  • 2021-05-18
  • 2021-10-16
  • 2021-11-03
猜你喜欢
  • 2021-08-30
  • 2022-12-23
  • 2021-05-05
  • 2021-08-29
  • 2021-11-14
  • 2022-12-23
  • 2021-12-09
相关资源
相似解决方案