学习日记0910线程池与进程池 同步调用与异步调用 函数回调 协程

前提:线程池与进程池一般与同步调用与异步调用一起使用,而函数回调一般与异步调用一起使用

同步调用

  提交完一个任务后,在原地等待,直到任务完完整整的运行完,得到返回的结果之后,再运行下一个函数,这样会导致任务之间是串行运行

  进程池+同步调用

from concurrent.futures import ProcessPoolExecutor
import time,os,random

def task(name):
    print('%s:%s' % (name, os.getpid()))
    time.sleep((random.randint(1, 3)))
    return 123


if __name__ == '__main__':
    p = ProcessPoolExecutor(4)
    for i in range(10):
        res = p.submit(task,'同步调用').result()
        print(res)
    p.shutdown(wait=True)

    print('主函数')

  进程池+异步调用+函数回调

from concurrent.futures import ProcessPoolExecutor
import time
import random, os


def task(name):
    print('%s:%s' % (name, os.getpid()))
    time.sleep((random.randint(1, 3)))
    return 123


def re_task(future):
    time.sleep(1)
    print('函数task的运行结果是%s:%s' % (future.result(), os.getpid()))


if __name__ == '__main__':
    p = ProcessPoolExecutor(4)
    for i in range(10):
        future = p.submit(task, 'pid')
        future.add_done_callback(re_task)  # 函数回调的代码,实现的是将future对象传递给re_task函数,实现了函数之间的解耦合
    p.shutdown(wait=True)

    print('zhu')

  线程池+同步调用

from concurrent.futures import ThreadPoolExecutor
from threading import current_thread
import time,random

def task(name):
    print('%s:%s' % (name, current_thread().name))
    time.sleep((random.randint(1, 3)))
    return 123

if __name__ == '__main__':
    t = ThreadPoolExecutor(4)
    for i in range(10):
        res = t.submit(task,'pid').result()
        print(res)
    t.shutdown(wait=True)
    print('zhu')

  线程池+异步调用+函数回调

from concurrent.futures import ThreadPoolExecutor
from threading import current_thread
import time,random

def task(name):
    print('%s:%s' % (name, current_thread().name))
    time.sleep((random.randint(1, 3)))
    return 123

def re_task(future):
    time.sleep(1)
    print('函数task的运行结果是%s:%s' % (future.result(), current_thread().name))


if __name__ == '__main__':
    t = ThreadPoolExecutor(4)
    for i in range(10):
        future = t.submit(task,'pid')
        future.add_done_callback(re_task)
    t.shutdown(wait=True)
    print('主线程!')

阻塞与非阻塞

  阻塞:程序正在处理I\O操作程序会进入阻塞状态

  非阻塞:程序正在处在运行状或者就绪态

程序的三种状态:

 协程

  只有在应用程序层次才有协程,在操作系统中没有协程这一说

  协程的作用:

    在单线程中实现并发

    如果在程序的执行过程遇到了I\O的操作,就利用协程执行切换操作,这样可以大幅度的提高效率

利用协程实现套接字并发

服务端

from gevent import monkey; monkey.patch_all()
from socket import *
from gevent import spawn


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(ip, port, backlog=5):
    server = socket(AF_INET, SOCK_STREAM)
    server.bind((ip, port))
    server.listen(backlog)

    while True:  # 链接循环
        conn, client_addr = server.accept()
        print(client_addr)

        # 通信
        spawn(comunicate, conn)


if __name__ == '__main__':
    g1 = spawn(server, '127.0.0.1', 8080)
    g1.join()

客户端

from threading import Thread,current_thread
from socket import *

def client():
    client=socket(AF_INET,SOCK_STREAM)
    client.connect(('127.0.0.1',8080))

    n=0
    while True:
        msg='%s say hello %s' %(current_thread().name,n)
        n+=1
        client.send(msg.encode('utf-8'))
        data=client.recv(1024)
        print(data.decode('utf-8'))

if __name__ == '__main__':
    for i in range(500):
        t=Thread(target=client)
        t.start()

 

posted @ 2018-09-10 14:53  周建豪  阅读(212)  评论(0编辑  收藏  举报