Python多进程向同⼀个⽂件写数据
1.遇到的问题:
之前,因为考虑到Python多进程可以充分利⽤CPU核数,提⾼程序的效率,所以就使⽤多进程写⽂件。但是向同⼀个⽂件写⼊数据的时候,由于多进程是并发进⾏,操作系统中会不清楚到底要写⼊哪个数据到⽂件中,所以会出现资源竞争混乱,导致⽂件内容轮乱。
不过你还可以给⽂件加锁,但是加锁⼀般会造成程序的执⾏速度下降,⽽且如果进程在多处需要向⽂件输出,也不好把这些代码整个都锁起来,如果都锁起来,那跟单进程还有什么区别。
2.解决思路如下:
跟把⽂件输出集中在⼀起也差不多,就是把进程需要写⼊⽂件的内容作为返回值返回给回调函数,使⽤回调函数向⽂件中写⼊内容。不过还有⼀种更加优雅的解决⽅式:使⽤multiprocessing库的回调函数功能。
3.应⽤场景:
进程池中任何⼀个任务⼀旦处理完了,就⽴即告知主进程:我好了,你可以处理我的结果了。主进程则
调⽤⼀个函数去处理该结果,该函数即回调函数。我们可以把耗时间(阻塞)的任务放到进程池中,然后指定回调函数(主进程负责执⾏),这样主进程在执⾏回调函数时就省去了I/O的过程,直接拿到的是任务的结果。
4.异步回调函数 apply_async
源代码如下,有兴趣可以看看:
def apply_async(self, func, args=(), kwds={}, callback=None,
error_callback=None):
'''
Asynchronous version of `apply()` method.
'''
if self._state != RUN:
raise ValueError("Pool not running")
result = ApplyResult(self._cache, callback, error_callback)
self._taskqueue.put(([(result._job,0, func, args, kwds)],None))
return result
参数解释下:
func 是调⽤的函数
args 是给指定的函数传递的参数,以元组的⽅式传递
kwargs:传递字典类型参数
callback:只能接受单个参数的可调⽤对象,当结果完成时就对象的callback回调函数
error_callback:只能⼀个接受单个参数的可调⽤对象。如果⽬标函数失败,则以该异常实例调⽤error_callback。
代码⽰例:
import multiprocessing
# 设置回调函数
def setcallback(x):
with open('','a+')as f:
line =str(x)+"\n"
f.write(line)
def multiplication(num):一个线程可以包含多个进程
return num*(num+1)
if __name__ =='__main__':
pool = multiprocessing.Pool(6)
for i in range(1000):
pool.apply_async(func=multiplication, args=(i,), callback=setcallback)
pool.close()
pool.join()
这是保存完毕的⽂件,部分内容,可以看出数据没有混乱。
总结:
apply_async是异步⾮阻塞式,不⽤等待当前进程执⾏完毕,随时跟进操作系统调度来进⾏进程切换,即多个进程并⾏执⾏,提⾼程序的执⾏效率。回调应该⽴即完成,否则处理结果的线程将被阻塞。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论