day 32

一.进程池与线程池

# def task(name):
#     print("%s%s is running " %(name,os.getpid()))
#     time.sleep(random.randint(1,3))
#
# if __name__ == '__main__':
#     p=ProcessPoolExecutor(4) #创建进程池的个数
#     #提交任务
#     #同步提交:提交完一个任务后,就在原地等待,等待任务完完整整地运行完毕后拿到结果,在执行下一行代码,会导致任务是串行执行的
#     #异步提交:提交完一个任务后,不在原地等待,而是直接执行下一行代码,会导致执行是并发的
#     li=[]
#     #同步提交
#     for i  in range(10):
#         # res = p.submit(task,'线程id:').result()
#         # print(res)
#
#     #异步提交
#
#         future=p.submit(task,"线程id:")
#         li.append(future)
#
#     p.shutdown(True)      #关闭进程池的入口,并且在原地等待进程池内所有任务运行完毕
#
#     for future in li:
#         print(future.result())
#     print("主")

二.

def get(url):
    print("%s GET %s" % (current_thread().name, url))
    time.sleep(3)
    response = requests.get(url)
    if response.status_code == 200:
        res = response.text
    else:
        res = '下载失败'
    return  res


def pase(future):
    time.sleep(1)
    res= future.result()
    print("%s 解析的结果为:%s" % (current_thread().name, len(res)))


if __name__ == '__main__':
    urls = ['http://www.baidu.com',
            'http://www.sina.com',
            'http://www.tmall.com',
            'http://www.jd.com',
            'http://www.python.org',
            'http://www.openstack.com'
            ]
    p = ProcessPoolExecutor(6)
    li = []
    strat = time.time()
    for url in urls:  # 可以理解为开启进程数的个数
        future = p.submit(get, url)
        future.add_done_callback(pase)  #pase会将任务运行完毕后会自动触发,然后接受一个参数futur对象
    p.shutdown(True)                    #关闭进程池的入口,并且在原地等待进程池内所有任务运行完毕
    print("", time.time() - strat)

 三.利用线程池和进程池实现套接字的并发

from socket import *
from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor
from multiprocessing import Process


def comunicate(conn):
    while True:  # 通信循环
        try:
            data = conn.recv(1024)
            if len(data) == 0: break
            conn.send(data.upper())
        except ConnectionResetError:
            break
    conn.close()


def server():
    server = socket(AF_INET, SOCK_STREAM)
    server.bind(("127.0.0.1", 8081))
    server.listen(5)

    while True:  # 链接循环
        conn, client_addr = server.accept()
        print(client_addr)
        # 通信
        t = Process(target=comunicate, args=(conn,))
        t.start()


if __name__ == '__main__':
    p = ProcessPoolExecutor(6)
    for i in range(4):
        future = p.submit(server, )
        # future.add_done_callback(comunicate)  # 回调函数   communciate会将任务运行完毕后会自动触发,然后接受一个参数futur对象

 四.协程

'''
1. 目标:
    在线程下实现并发
        并发(多个任务看起来是同时执行就是并发):切换+保存状态

2. 协程:
    协程是单线程实现并发
    注意:协程是程序员意淫出来的东西,操作系统里只有进程和线程的概念(操作系统调度的是线程)

    在单线程下实现多个任务间遇到IO就切换就可以降低单线程的IO时间,从而最大限度地提升单线程的效率


'''

#串行执行
import time

def func1():
    for i in range(10000000):
        i+1

def func2():
    for i in range(10000000):
        i+1

start = time.time()
func1()
func2()
stop = time.time()
print(stop - start)


#基于yield并发执行
import time
def func1():
    while True:
        print('func1')
        10000000+1
        yield

def func2():
    g=func1()
    for i in range(10000000):
        print('func2')
        time.sleep(100)
        i+1
        next(g)

start=time.time()
func2()
stop=time.time()
print(stop-start)

五.

from gevent import monkey;monkey.patch_all()
from gevent import spawn,joinall #pip3 install gevent
import time

def play(name):
    print('%s play 1' %name)
    time.sleep(5)
    print('%s play 2' %name)

def eat(name):
    print('%s eat 1' %name)
    time.sleep(3)
    print('%s eat 2' %name)


start=time.time()
g1=spawn(play,'刘清正')
g2=spawn(eat,'刘清正')

# g1.join()
# g2.join()
joinall([g1,g2])
print('',time.time()-start)
原文地址:https://www.cnblogs.com/jxl123/p/9619761.html