单线程并发

1-了解socket使用


def get_data(key):
    # 创建一个socket对象
    client = socket.socket()


    # 跟百度创建连接  处于堵塞状态
    client.connect(('www.baidu.com', 80))

    # 告诉百度我要什么
    client.sendall(b"GET /s?wd=%s HTTP/1.0\r\nhost: www.baidu.com\r\n\r\n" % key)

    # 接收百度发给我的信息
    chunk_list = []
    while True:
        chunk = client.recv(1000)
        if not chunk:
            break
        chunk_list.append(chunk)
    body = b"".join(chunk_list).decode('utf-8')
    print(body)


if __name__ == '__main__':

    list_1 = ['alex', 'db', 'sb']
    # for x in list_1:
    #    get_data(x)

    for x in list_1:
        print(x)
        t = threading.Thread(target=get_data, args=(x,))     # 创建线程
        t.start()

2-了解非堵塞

如何让socket 不堵塞
setblocking(False) 这样 socket 就不堵塞了
但是也是存在一些问题,报错后面都会 那那就需要用try捕获

try:
    client.connect(('www.baidu.com', 80))  # 执行报错
except BlockingIOError:
    pass

3-IO多路复用

它是用来监控的 数据的读于写 enmm应该IO数据
方式1 : select
方式2:pool
方式3:epool 不过后两种win用不了

import select
 r_list, w_list, e_list = select.select(socket_list, conn_list, [], 0.005)
 # r_list   表示可以可以读
 #w_list  表示可写

4-IO多路复用示例

需要学习的是封装思想
为什么要学习封装思想 ? 因这样子可以保留以前的数据不需要进行修改

import socket
import select


class Req(object):
    def __init__(self, sk, func):
        self.sk = sk
        self.func = func

    def fileno(self):
        return self.sk.fileno()


class NB(object):
    def __init__(self):
        self.conn_list = []
        self.socket_list = []

    def add(self, url, func):
        client = socket.socket()
        client.setblocking(False)
        try:
            client.connect((url, 80))
        except BlockingIOError as e:
            pass
        obj = Req(client, func)
        self.conn_list.append(obj)
        self.socket_list.append(obj)

    def run(self):
        while True:
            r_list, w_list, e_list = select.select(self.socket_list, self.conn_list, [], 0.005)  # 检测是否发生变化
            #  w_list有数据 表示已经连接成功了
            for sk in w_list:
                sk.sk.sendall(b"GET /s?wd=li HTTP/1.0\r\nhost:www.baidu.com\r\n\r\n")
                self.conn_list.remove(sk)
            for sk in r_list:
                sk_list = []
                while True:
                    try:
                        response = sk.sk.recv(1000)
                        if not response:
                            break
                        sk_list.append(response)
                    except BlockingIOError as e:
                        break

                data = b"".join(sk_list)
                sk.func(data)
                sk.sk.close()
                self.socket_list.remove(sk)

            if not self.socket_list:
                break

def baidu_response(data):
    print('百度', data)


def bing_response(data):
    print('bing', data)


def sogou_response(data):
    print('搜狗', data)


t1 = NB()
t1.add("www.baidu.com", baidu_response)
t1.add("cn.bing.com", bing_response)
t1.add("wwww.sogou.com", sogou_response)
t1.run()

5-认识协程

线程是不存在的
协程是 简单说微线程
对线程进行分片 理解 让程序自由执行
单纯的协程是没什么用的 需要和IO切换一起才厉害

import greenlet  # 这才是协程模块


def f1():
    print('你好')
    gr2.switch()
    print(22)
    gr2.switch()

def f2():
    print('hello')
    gr1.switch()
    print(11)


# 创建协程
gr1 = greenlet.greenlet(f1)
gr2 = greenlet.greenlet(f2)

IO切换

gevent 模块
记得 patch_all() 一定要在前面 不然就会报错

from gevent import monkey
monkey.patch_all()  # 遇到IO就切换
import gevent
import requests


def get_page(url):
    req = requests.get(url)
    print(url, req.content)


def get_page1(url):
    req = requests.get(url)
    print(url, req.content)


def get_page2(url):
    req = requests.get(url)
    print(url, req.content)


gevent.joinall([
    gevent.spawn(get_page, 'https://www.baidu.com'),
    gevent.spawn(get_page1, 'https://translate.google.cn'),
    gevent.spawn(get_page2, 'https://www.bilibili.com'),
])
# 这里就在调用了

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值