Python之多线程和多进程

   

一、多线程

1、顺序执行单个线程,注意要顺序执行的话,需要用join。

 1 #coding=utf-8
 2 
 3 from threading import Thread
 4 import time
 5 
 6 def my_counter():
 7     i = 0
 8     for _ in range(100000000):
 9         i = i + 1
10     return True
11 
12 def main():
13     thread_array = {}
14     start_time = time.time()
15     for tid in range(2):
16         t = Thread(target=my_counter)
17         t.start()
18         # join阻塞下个线程,除非当前线程执行完毕
19         t.join()
20     end_time = time.time()
21     print("Total time: {}".format(end_time - start_time))
22 
23 if __name__ == '__main__':

 执行结果: 

 

2、同时执行两个并发线程

 1 #coding=utf-8
 2 
 3 from threading import Thread
 4 import time
 5 
 6 def prn_obj(obj):
 7     return '\n'.join(['%s:%s' % item for item in obj.__dict__.items()])
 8 
 9 def my_counter():
10     i = 0
11     for _ in range(100000000):
12         i = i + 1
13     return True
14 
15 def main():
16     thread_array = {}
17     start_time = time.time()
18     for tid in range(2):
19         t = Thread(target=my_counter)
20         t.start()
21         thread_array[tid] = t
22     for i in range(2):
23         thread_array[i].join()
24         # print("thread type: {}".format(prn_obj(thread_array[i])))
25         print("thread type: {}".format(thread_array[i].name))
26     end_time = time.time()
27     print("Total time: {}".format(end_time - start_time))
28 
29 if __name__ == '__main__':
30     main()

下面是用了打印所有属性的方法,这个方法代码中注释了,可重复利用的代码块

 

二、多进程

1、multiprocessing

multiprocessing是跨平台版本的多进程模块,它提供了一个Process类来代表一个进程对象,下面是示例嗲吗

import os
if __name__=='__main__': 
    print 'Process (%s) start...' % os.getpid()
    pid = os.fork()
    print pid
    if pid==0:
            print 'I am child process (%s) and my parent is %s.' % (os.getpid(), os.getppid())
    else:
            print 'I (%s) just created a child process (%s).' % (os.getpid(), pid)

这个程序如果用单进程写则需要执行10秒以上的时间,而用多进程则启动10个进程并行执行,只需要用1秒多的时间。

 

在python中建议使用多进程而不是多线程,因为在python的多线程中有个全局解释器锁,这样在做并发效率会不是很高。

进程和进程直接可以用不同的全局解释器锁,可以提高程序效率。

 

2、进程间通信Queue

进程和进程之前是独立的,如果需要通信就需要Queue创建的对象来处理

 1 from multiprocessing import Process,Queue
 2 import time
 3 
 4 def write(q):
 5     for i in ['A','B','C','D','E']:
 6         print('Put %s to queue' % i)
 7         q.put(i)
 8         time.sleep(0.5)
 9 
10 def read(q):
11     while True:
12         v = q.get(True)
13         print('get %s form queue' %v)
14 
15 if __name__ == '__main__':
16     q = Queue()
17     pw = Process(target=write,args=(q,))
18     pr = Process(target=read,args=(q,))
19     pw.start()
20     pr.start()
21     pr.join()
22     pr.terminate()

 

3、进程池Pool

 1 #coding=utf-8
 2 
 3 from multiprocessing import Pool
 4 import time
 5 
 6 def f(x):
 7     print x*x
 8     time.sleep(2)
 9     return x*x
10 
11 if __name__ == '__main__':
12     '''定义启动的进程数量'''
13     pool = Pool(processes=5)
14     res_list = []
15 
16     for i in range(10):
17         '''
18         以异步并行的方式启动进程,如果要同步等待的方式,
19         可以在每次启动进程之后调用res.get()方法
20         也可以使用Pool.appley
21         '''
22         res = pool.apply_async(f,[i,])
23         print('--------:',i)
24         res_list.append(res)
25     pool.close()
26     pool.join()
27     for r in res_list:
28         print "result",(r.get(timeout=5))

 

 三、多线程与多进程的对比

在一般情况下多个进程的内存资源是相互独立的,而多线程可以共享同一个进程中的内存资源

 1 #coding=utf-8
 2 
 3 from multiprocessing import Process
 4 import threading
 5 import time
 6 lock = threading.Lock()
 7 
 8 def run(info_list,n):
 9     lock.acquire()
10     info_list.append(n)
11     lock.release()
12     print('%s' % info_list)
13 
14 if __name__ == '__main__':
15     info = []
16     for i in range(10):
17         # target为子进程执行的函数,args为需要给函数传递的参数
18         p = Process(target=run,args=[info,i])
19         p.start()
20         p.join()
21     time.sleep(1)#这里为了输出整齐让主进程的执行等一下子进程
22     print('-------------------threading---------------------')
23     for i in xrange(1,10):
24         p = threading.Thread(target=run,args=[info,i])
25         p.start()
26         p.join()

 

posted @ 2017-06-24 14:39  何杨  阅读(714)  评论(1编辑  收藏  举报