Python 学习 —— 多线程/协程

版权声明:转载注明出处 https://blog.csdn.net/qq_19428987/article/details/87867075

多线程类似同时执行多个不同的程序,多线程特点:

  • 使用多线程可以把占据时间长的程序中的任务放到后台处理;
  • 增加过度界面;
  • 可能加快程序的运行速度
  • 在用户输入、文件读写和网络收发数据线程会比较有用
  • 线程可以被抢占
  • 在其他线程正在运行时,线程可以暂时搁置

threading 方法

在Python2中提供了thread 在Python3中改成了-thread,不过一般不会使用,会采用Python通用的多线程包threading:

  • threading.Thread(target=loop1,args=()):直接调用注意,如果参数只有一个,后面必须加上逗号。抛出一个线程
    -start():调用start()启动线程
    -join():等待线程结束
    print("Starting at:",time.ctime())
    thread1=threading.Thread(target=loop1)
    thread2=threading.Thread(target=loop2)
    thread1.start()
    thread2.start()
    thread1.join()
    thread2.join()
    print("All done at:",time.ctime())
    
  • 用lock.acquire和lock.release,来对数据进行保护,防止在多线程操作时数据错误。注意申请了锁之后必须解锁。
  • 线程不安全类型:list、set、dict
  • 线程安全类型:queue
  • threading.Timer(scond,fun):指定时间后调用指定的函数

线程替代方案

在使用多线程时需要考虑到线程安全,死锁,以及可能潜在的线程资源竞争的问题,线程的切换也会带来性能的消耗,Python提供了进程的方案来替代线程。(进程之间无任何共享状态):

  • subprocess:完全跳过线程,使用进程,是派生进程的替代方案(Python2.4)

  • mutiprocessiong:使用threading接口派生,使用子进程,允许多核或者多CPU派生(Python2.6):

    p=multiprocessing.Process(target=clock,args=(5,))
    p.start()
  • concurrent.futures:新的异步执行模块,任务级别的操作(Python3.2之后引入)
    concurrent.futures会以子进程的形式,平行的运行多个python解释器,从而令python程序可以利用多核CPU来提升执行速度。由于子进程与主解释器相分离,所以他们的全局解释器锁也是相互独立的。每个子进程都能够完整的使用一个CPU内核。

协程

  • 生成器——generator:一边循环一边计算下一个元素的机制/算法。
    (1)每次调用都产生出for循环需要的下一个元素
    (2)如果到达最后一个,爆出Stoplteration异常
    (3)可以被next函数调用

  • Python3.4 引入协程,用yield实现

  • 实现协程的包:asyncio、tornado、gevent

  • 协程定义:是为非抢占式多任务子程序的计算机程序组件,协程允许不同入口点在不同位置暂停或者开始执行程序

  • 协程实现:yiled返回和send调用

  • yiled from: 后面需要加的是可迭代对象,它可以是普通的可迭代对象,也可以是迭代器,甚至是生成器

def simple_coroutinue():
    print("->Start")
    x=yield
    print("->recived",x)
if __name__ == '__main__':
    sc=simple_coroutinue()
    print("StartCoroutinue")
    next(sc)
    print(".........")
    sc.send("Python")
 输出结果:
 StartCoroutinue
->Start
.........
->recived Python

asyncio

Python 3.4 开始引入标准库中,内置对异步IO支持

  • 步骤:
    (1)创建消息循环
    (2)把协程导入
    (3)关闭(必须要关闭)
import threading
import asyncio
@asyncio.coroutine
def hello():
    print("Hello world! ({0})".format(threading.currentThread()))
    print("Start.........({0})".format(threading.currentThread()))
    yield from asyncio.sleep(2)
    print("Done.......({0})".format(threading.currentThread()))
    print("Hello again! ({0})".format(threading.currentThread()))
loop=asyncio.get_event_loop()
tasks=[hello(),hello()]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
输出结果:
Hello world! (<_MainThread(MainThread, started 10112)>)
Start.........(<_MainThread(MainThread, started 10112)>)
Hello world! (<_MainThread(MainThread, started 10112)>)
Start.........(<_MainThread(MainThread, started 10112)>)
Done.......(<_MainThread(MainThread, started 10112)>)
Hello again! (<_MainThread(MainThread, started 10112)>)
Done.......(<_MainThread(MainThread, started 10112)>)
Hello again! (<_MainThread(MainThread, started 10112)>)
  • async and await
    Python 3.5 后用async替换@asyncio.coroutine、用await 替换 yield from
    -asyncio 实现单线程的并发IO,在客户端用处不大
    -asyncio实现了tcp,udp,ssl等协议

aiohttp

在服务器端可以asyncio+coroutine配合,因为HTTP是IO操作。aiohttp是asyncio实现的http框架。

Python关于多线程/多进程大概只是粗略的了解了一些概念定义,之后再实践中深入理解之后再来更新这一篇我自己都惨不忍睹的博客

猜你喜欢

转载自blog.csdn.net/qq_19428987/article/details/87867075
今日推荐