-
进程同步
进程与进程之间相互独立是不是就不需要同步了呢?答案是否定的,计算机系统有很多东西比如不允许多个并发进程同时访问临界资源,临时区等
临界资源和临界区(临界部分)
- 临界资源:一次只能供一个进程访问的资源。
- 临界区:把不允许多个并发进程交叉执行的一段程序称为临界区(critical region)或临界部分(critical section)。
临界区是由属于不同并发进程的程序段共享公用数据或公用数据变量而引起的,临界区不可能用增加硬件的方法来解决。因此,临界区也可以被称为访问公用数据的那段程序。
当一个进程使用该临界资源时,其他需要访问该资源的进程必须阻塞,直到占用者释放该资源。
一般情况下,作为程序段的一个过程不允许多个进程同时访问它。但如果该过程是纯过程,则各并发进程可以同时访问它。纯过程是指在执行过程中不改变过程自身代码的一类过程。
进程里面也有 Lock来实现同步,这里直接给大家代码
from multiprocessing import Process ,Lock
import time
def f(l,i):
with l:
print("hello world %s"%i) # 不加所会输出会串行
if __name__ == "__main__":
lock=Lock()
for num in range(10):
Process(target=f,args=(lock,num)).start()
在不加锁的话可能会出现两行打印成一行的情况
-
进程池
进程池内部维护者一个进程序列,当使用时,则去进程池中获取一个进程,如果进程池序列中没有可以供使用的进程,纳闷进程就会等待,直到进程池中有可用进程为止。
在利用Python进行系统管理的时候,特别是同时操作多个文件目录,或者远程控制多台主机,并行操作可以节约大量的时间。当被操作对象数目不大时,可以直接利用multiprocessing中的Process动态成生多个进程,十几个还好,但如果是上百个,上千个目标,手动的去限制进程数量却又太过繁琐,此时可以发挥进程池的功效。
- apply_async(func[, args[, kwds[, callback]]]) 它是非阻塞,apply(func[, args[, kwds]])是阻塞的(理解区别,看例1例2结果区别)
- close() 关闭pool,使其不在接受新的任务。
- terminate() 结束工作进程,不在处理未完成的任务。
- join() 主进程阻塞,等待子进程的退出, join方法要在close或terminate之后使用。
- get()函数得出每个返回结果的值
from multiprocessing import Process ,Pool
import time,os
def Foo(i):
time.sleep(1)
#print(i)
return i+100 #将返回的值付作为Bar参数
def Bar(arg):
print("从Foo 获得的返回值:",arg)
pool = Pool(5) #一次只允许5个进程
Bar(1)
print("主进程",os.getppid())
for i in range(100):
#pool.apply(func=Foo,args=(i,))#同步
#回调函数是主进程调用-----一般把共用的东西让回调处理
pool.apply_async(func=Foo,args=(i,),callback=Bar) #异步
pool.close()
pool.join()
print("end")