python多线程、多进程、协程的使用

本文主要介绍多线程、多进程、协程的最多见使用,每一个的详细说明与介绍有时间会在之后的随笔中体现。python

1、多线程多线程

1.python经过两个标准库thread和threading提供对线程的支持。thread提供了低级别的、原始的线程以及一个简单的锁。threading经过对thread模块进行二次封装,提供了更方便的API来操做线程。接下来只介绍threading的常见用法。app

2.使用函数

import threading
import time 


def Traversal_5(interval):
    for i in xrange(5):
        print 'Traversal_5:',i
        time.sleep(interval)

def Traversal_10(interval):
    for i in xrange(10):
        print 'Traversal_10:',i
        time.sleep(interval)

if __name__ == '__main__':
    print 'start time:'
    t1 = int(time.time()) 
    tasks=[Traversal_5,Traversal_10] 
    threads = []
    for task in tasks:
        t = threading.Thread(target=task,args=(1,))
        threads.append(t)
    for t in threads:
        t.setDaemon(True)
        t.start()
    for t in threads:
        t.join()
    print 'end main total time:',int(time.time())-t1

3.结果性能

4.结果分析spa

单线程运行这完两个函数至少应该须要15秒,多线程状况下,两个函数同时运行,总共用时是取最长的Traversal_10这个函数的时间线程

2、多进程code

1.因为GIL的存在,python中的多线程其实并非真正的多线程,若是想要充分地使用多核CPU的资源,在python中大部分状况须要使用多进程。Python提供了很是好用的多进程包multiprocessing,与threading.Thread相似,它能够利用multiprocessing.Process对象来建立一个进程。接下来只介绍multiprocessing的常见用法。协程

2.使用对象

import multiprocessing 
import time 

class Traversal(object):
    def __init__(self,interval, name):
        self.interval = interval 
        self.name = name
        self._rungevent(self.interval, self.name)

    def _rungevent(self, interval, name):
        for i in xrange(5):
            print 'process name:',name,'\tindex:',i
            time.sleep(interval)

if __name__ == '__main__':
    print 'start time:'
    t1 = int(time.time()) 
    jobs = []
    for x in xrange(2):
        p = multiprocessing.Process(target = Traversal, args=(1,'Traversal_'+str(x)))
        p.start()
        jobs.append(p)
    for job in jobs:
        job.join() 
    print 'end main total time:',int(time.time())-t1

3.结果

4.结果分析

此程序至关于遍历两次0-5的函数,按理说,时间应该是10秒,由于开了2个进程,因此总花时和一次遍历时间相等

3、协程

1.协程,又称微线程,纤程。协程的特色在因而一个线程执行,那和多线程比,协程有何优点?最大的优点就是协程极高的执行效率。由于子程序切换不是线程切换,而是由程序自身控制,所以,没有线程切换的开销,和多线程比,线程数量越多,协程的性能优点就越明显。第三方的gevent为Python提供了比较完善的协程支持。接下来只介绍gevent用法

2.使用

from gevent import monkey; monkey.patch_all(); 
from gevent.pool import Pool 
import time 

def Traversal(job):
    print 'job:',job
    time.sleep(1)


if __name__ == '__main__':
    print 'start time:'
    t1 = int(time.time())
    jobs = [i for i in xrange(10)] 
    pool = Pool(5)
    pool.map(Traversal, jobs)
    print 'end main total time:',int(time.time())-t1

3.结果

3.结果分析

此程序本质是遍历0-10之间的数,应该用时10秒,因为使用了协程,开启了5个池,因此时间减小到2秒,大大减小运行时间。

4、多进程+协程

1.由于协程是一个线程执行,那怎么利用多核CPU呢?最简单的方法是多进程+协程,既充分利用多核,又充分发挥协程的高效率,可得到极高的性能。

2.使用

import multiprocessing 
from gevent import monkey; monkey.patch_all(); 
from gevent.pool import Pool
import time 

def Traver(job):
    print 'job:',job
    time.sleep(1)

class Traversal(object):
    def __init__(self,interval, name):
        self.interval = interval 
        self.name = name
        self._rungevent(self.interval, self.name)

    def _rungevent(self, interval, name):
        jobs = [i for i in xrange(5)] 
        pool = Pool(5)
        pool.map(Traver, jobs) 

if __name__ == '__main__':
    print 'start time:'
    t1 = int(time.time()) 
    jobs = []
    for x in xrange(2):
        p = multiprocessing.Process(target = Traversal, args=(1,'Traversal_'+str(x)))
        p.start()
        jobs.append(p)
    for job in jobs:
        job.join() 
    print 'end main total time:',int(time.time())-t1

3.结果

4.结果分析

此程序本质上是遍历2次0-5之间数据,应该使用10秒才能运行完,因为开启了两个线程和5个池的协程,结果1秒就运行完了。

5、总结

从以上小例子看,多进程、多线程和协程没有啥差异,本文也只是主要介绍其用法。可是,要是在IO密集和CPU密集的任务下,各个之间的区别就会显现,这里就不作介绍。

相关文章
相关标签/搜索