同步、异步
同步:多个线程之间按照既定的顺序合理地调度,即执行过程是有规律的。如:你 喊 你朋友吃饭 ,你朋友在忙 ,你就一直在那等,等你朋友忙完了 ,你们一起去。
在下面的例子中创建了三个线程t1,t2,t3和三把锁m1,m2,m3。主进程先对m2和m3上锁,然后开启三个线程。在t1中对m1上锁,执行完后释放m2;在t2中由于m2一开始已经上锁,因此只能等t1中m2释放后再执行,同理t3必须等t2中m3释放后才能执行。这样通过三把锁合理的上锁、解锁就达到三个线程同步的效果。
#coding=utf-8
import threading
import time
def do_thread1():
for i in range(3):
mutex1.acquire()
print('in thread1...')
time.sleep(1)
mutex2.release()
def do_thread2():
for i in range(3):
mutex2.acquire()
print('in thread2...')
time.sleep(1)
mutex3.release()
def do_thread3():
for i in range(3):
mutex3.acquire()
print('in thread3...')
time.sleep(1)
mutex1.release()
if __name__ == '__main__':
print('------------main thread begin-------')
mutex1 = threading.Lock()
mutex2 = threading.Lock()
mutex3 = threading.Lock()
mutex2.acquire()
mutex3.acquire()
t1 = threading.Thread(target=do_thread1)
t2 = threading.Thread(target=do_thread2)
t3 = threading.Thread(target=do_thread3)
t1.start()
t2.start()
t3.start()
t1.join()
t2.join()
t3.join()
print('------------main thread over-------')
结果:
------------main thread begin-------
in thread1...
in thread2...
in thread3...
in thread1...
in thread2...
in thread3...
in thread1...
in thread2...
in thread3...
------------main thread over-------
异步:而调用者不用等待其结果的返回而可以做其它的事情。如:你 喊 你朋友吃饭 ,你朋友说知道了 ,待会忙完去找你 ,你就去做别的了。
下面代码中创建了进程池pool,使用非阻塞方式把Foo函数传入。与以往不同的是多了第三个参数callback,bar函数作为的哥第三个参数传入。在进程中的函数Foo中他该需要2s就能执行完,而主进程在却停了5s。因此进程池中的函数先执行完,然后通知给主进程,主进程得到子进程的信号后转到回调函数bar中执行,回调函数执行完后再次回到主进程执行。需要注意的就是注释中的join()用法以及bar的参数来自进程池函数的返回值。
from multiprocessing import Pool,Process
import time,os
def Foo(a):#创建函数
time.sleep(2)
print('in the process:',os.getpid(),os.getppid())
#return a+100
return 'value will be given callback'
def bar(arga):#创建函数
print('in the process:', os.getpid(), os.getppid())
print(arga)
if __name__ == '__main__':
print('父进程ID:',os.getpid())
pool = Pool()
#for i in range(10):#创建10个进程
pool.apply_async(func=Foo,args=(10,),callback=bar)
#创建线程,参数1调用函数,参数2设置i为函数FOO参数,参数3为返回函数
#参数三为回调函数,将FOO函数的返回值作为参数调用bar函数。
#pool.apply(func=Foo,args=(i,),callback=bar)#串行
#pool.apply_async(func=Foo,args=(i,),callback=bar)#并行
pool.close()#关闭
pool.join()#如果没有.join语句,程序不执行就会关闭。这里是个大坑。
print('----------------main over------------')
结果:
父进程ID: 5436
in the process: 3832 5436
in the process: 5436 11444
value will be given callback
----------------main over------------