1.单线程解决并发

方式一

import socket
import select

# 百度创建连接:非阻塞
client1 = socket.socket()
client1.setblocking(False)
try:
    client1.connect(('www.baidu.com', 80))
except BlockingIOError as e:
    pass

# 搜狗创建连接:非阻塞
client2 = socket.socket()
client2.setblocking(False)
try:
    client2.connect(('www.sogou.com', 80))
except BlockingIOError as e:
    pass

# GitHub创建连接:非阻塞
client3 = socket.socket()
client3.setblocking(False)
try:
    client3.connect(('www.github.com', 80))
except BlockingIOError as e:
    pass

# 创建socket列表:socket_list
socket_list = [client1, client2, client3]
# 创建connect列表:conn_list
conn_list = [client1, client2, client3]

while True:
    rlist, wlist, elist = select.select(socket_list, conn_list, [], 0.005)
	# rlist中表示已近获取数据的socket对象
    # wlist中表示已经连接成功的socket对象
	# elist中表示出现错误的socket对象
    for sk in wlist:
        if sk == client1:
            sk.sendall(b'GET /s?wd=alex HTTP/1.0\r\nhost:www.baidu.com\r\n\r\n')
        elif sk == client2:
            sk.sendall(b'GET /web?query=fdf HTTP/1.0\r\nhost:www.sogou.com\r\n\r\n')
        else:
            sk.sendall(b'GET /s?wd=alex HTTP/1.0\r\nhost:www.oldboyedu.com\r\n\r\n')
        conn_list.remove(sk)
    for sk in rlist:
        chunk_list = []
        while True:
            try:
                chunk = sk.recv(8096)
                if not chunk:
                    break
                chunk_list.append(chunk)
            except BlockingIOError as e:
                break
        body = b''.join(chunk_list)
        # print(body.decode('utf-8'))
        print('------------>', body)
        sk.close()
        socket_list.remove(sk)
    if not socket_list:
        break

方式二

import socket
import select

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

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


class Nb(object):

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

    def add(self,url,func):
		# 创建socket客户端
        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)
		# socket列表
        self.socket_list.append(obj)

    def run(self):

        while True:
            rlist,wlist,elist = select.select(self.socket_list,self.conn_list,[],0.005)
            # wlist中表示已经连接成功的req对象
            for sk in wlist:
                # 发生变换的req对象
                sk.sock.sendall(b'GET /s?wd=alex HTTP/1.0\r\nhost:www.baidu.com\r\n\r\n')
                self.conn_list.remove(sk)
            for sk in rlist:
                chunk_list = []
                while True:
                    try:
                        chunk = sk.sock.recv(8096)
                        if not chunk:
                            break
                        chunk_list.append(chunk)
                    except BlockingIOError as e:
                        break
                body = b''.join(chunk_list)
                # print(body.decode('utf-8'))
                sk.func(body)
                sk.sock.close()
                self.socket_list.remove(sk)
            if not self.socket_list:
                break


def baidu_repsonse(body):
    print('百度下载结果:',body)

def sogou_repsonse(body):
    print('搜狗下载结果:', body)

def github_repsonse(body):
    print('GITHUB下载结果:', body)


t1 = Nb()
t1.add('www.baidu.com',baidu_repsonse)
t1.add('www.sogou.com',sogou_repsonse)
t1.add('www.github.com',oldboyedu_repsonse)
t1.run()