Python 进程
|
1
2
3
4
5
6
7
8
9
10
|
from multiprocessing import Processimport threadingimport time def foo(i): print 'say hi',i for i in range(10): p = Process(target=foo,args=(i,)) p.start() |
注意:由于进程之间的数据需要各自持有一份,所以创建进程需要的非常大的开销。
进程数据共享
进程各自持有一份数据,默认无法共享数据
1 #方法一,Array 2 from multiprocessing import Process,Array 3 temp = Array('i', [11,22,33,44]) 4 5 def Foo(i): 6 temp[i] = 100+i 7 for item in temp: 8 print i,'----->',item 9 10 for i in range(2): 11 p = Process(target=Foo,args=(i,)) 12 p.start() 13 14 #方法二:manage.dict()共享数据 15 from multiprocessing import Process,Manager 16 17 manage = Manager() 18 dic = manage.dict() 19 20 def Foo(i): 21 dic[i] = 100+i 22 print dic.values() 23 24 for i in range(2): 25 p = Process(target=Foo,args=(i,)) 26 p.start() 27 p.join()
'c': ctypes.c_char, 'u': ctypes.c_wchar, 'b': ctypes.c_byte, 'B': ctypes.c_ubyte, 'h': ctypes.c_short, 'H': ctypes.c_ushort, 'i': ctypes.c_int, 'I': ctypes.c_uint, 'l': ctypes.c_long, 'L': ctypes.c_ulong, 'f': ctypes.c_float, 'd': ctypes.c_double
from multiprocessing import Process, Queue def f(i,q): print(i,q.get()) if __name__ == '__main__': q = Queue() q.put("h1") q.put("h2") q.put("h3") for i in range(10): p = Process(target=f, args=(i,q,)) p.start()
当创建进程时(非使用时),共享数据会被拿到子进程中,当进程中执行完毕后,再赋值给原值。
#!/usr/bin/env python # -*- coding:utf-8 -*- from multiprocessing import Process, Array, RLock def Foo(lock,temp,i): """ 将第0个数加100 """ lock.acquire() temp[0] = 100+i for item in temp: print i,'----->',item lock.release() lock = RLock() temp = Array('i', [11, 22, 33, 44]) for i in range(20): p = Process(target=Foo,args=(lock,temp,i,)) p.start()
进程池
进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程,如果进程池序列中没有可供使用的进进程,那么程序就会等待,直到进程池中有可用进程为止。
进程池中有两个方法:
- apply
- apply_async
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
#!/usr/bin/env python# -*- coding:utf-8 -*-from multiprocessing import Process,Poolimport time def Foo(i): time.sleep(2) return i+100 def Bar(arg): print arg pool = Pool(5)#print pool.apply(Foo,(1,))#print pool.apply_async(func =Foo, args=(1,)).get() for i in range(10): pool.apply_async(func=Foo, args=(i,),callback=Bar) print 'end'pool.close()pool.join()#进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。 |
协程
线程和进程的操作是由程序触发系统接口,最后的执行者是系统;协程的操作则是程序员。
协程存在的意义:对于多线程应用,CPU通过切片的方式来切换线程间的执行,线程切换时需要耗时(保存状态,下次继续)。协程,则只使用一个线程,在一个线程中规定某个代码块执行顺序。
协程的适用场景:当程序中存在大量不需要CPU的操作时(IO),适用于协程;
greenlet
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
#!/usr/bin/env python# -*- coding:utf-8 -*-from greenlet import greenletdef test1(): print 12 gr2.switch() print 34 gr2.switch()def test2(): print 56 gr1.switch() print 78gr1 = greenlet(test1)gr2 = greenlet(test2)gr1.switch() |
gevent
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
import geventdef foo(): print('Running in foo') gevent.sleep(0) print('Explicit context switch to foo again')def bar(): print('Explicit context to bar') gevent.sleep(0) print('Implicit context switch back to bar')gevent.joinall([ gevent.spawn(foo), gevent.spawn(bar),]) |
遇到IO操作自动切换:
from gevent import monkey; monkey.patch_all() import gevent import urllib2 def f(url): print('GET: %s' % url) resp = urllib2.urlopen(url) data = resp.read() print('%d bytes received from %s.' % (len(data), url)) gevent.joinall([ gevent.spawn(f, 'https://www.python.org/'), gevent.spawn(f, 'https://www.yahoo.com/'), gevent.spawn(f, 'https://github.com/'), ])
浙公网安备 33010602011771号