python 多线程读写文件_python 关于多进程与多线程且写入同一文件情况

目录[-]

python 关于多进程与多线程且写入同一文件情况

任何语言学习多进程与多线程这都市必要的,最近在学习过程中涉及诸多多进程和多线程的情况,但是多进程之间文件是相互独立的,容易发生资源争抢的问题,造成资源的抢夺,同时写入文件使之卡住,由于不规律随机的原因,写入文件的数据也可能是乱码

多进程写入文件

关于网上所整理的一些资料来看,处理的方式各不相同

1.使用进程锁,multiprocessing使用join()方法对进程进行阻塞

2.使用文件锁,python 内置文件锁模块 fcntl

这是解决的两个方法,python的多进程不像linux环境下的多进程一样,linux下的multiprocessing库是基于fork函数,父进程fork了一个子进程之后 ,比如文件句柄都传递给子进程,但是在windows下如果打开一个文件,在子进程中写入会出现ValueError: I/O operation on closed file这样的错误,所以我们在windows下必须在if name == 'main'下使用多进程。

multiprocessing模块

之前我们刚刚说了multiprocessing模块在linux上支持比较好,但是python是跨平台语言。所以这个包提供了一个Process类来代表一个进程对象。这是multiprocessing的核心,,与threading很类似,但是对CPU的利用率会提高。

我们看一下Process类的构造方法:

init(self, group=None, target=None, name=None, args=(), kwargs={})

参数说明:group:进程所属组。基本不用

target:表示调用对象。

args:表示调用对象的位置参数元组。

name:别名

kwargs:表示调用对象的字典。

我们接一个简单的例子说明:

import multiprocessing

def func(n):

#获取进程名称

name = multiprocessing.current_process().name

print(name)

return

if name == 'main' :

numList = []

for i in xrange(5) :

p = multiprocessing.Process(target=do, args=(i,))

numList.append(p)

p.start()

p.join()

print("Process end.")

这只是一个简单的用法,我们看看multiprocessing的POOL

POOL类

POOL模块下的各个方法apply(func[, args=()[, kwds={}]])

该函数用于传递不定参数,同python中的apply函数一致,主进程会被阻塞直到函数执行结束

apply_async(func[, args=()[, kwds={}[, callback=None]]])

与apply用法一致,但它是非阻塞的且支持结果返回后进行回调。

map(func, iterable[, chunksize=None])

Pool类中的map方法,与内置的map函数用法行为基本一致,它会使进程阻塞直到结果返回。 注意:虽然第二个参数是一个迭代器,但在实际使用中,必须在整个队列都就绪后,程序才会运行子进程。

map_async(func, iterable[, chunksize[, callback]])

与map用法一致,但是它是非阻塞的。其有关事项见apply_async

close()

关闭进程池(pool),使其不在接受新的任务。

terminal()

结束工作进程,不在处理未处理的任务。

join()

主进程阻塞等待子进程的退出, join方法要在close或terminate之后使用。

不同方法下的解决方式

方法一使用进程锁:from multiprocessing import Pool

def run(x):

return "test"+str(x)

def write_(s):

with open("test.csv","a+",encoding="utf8") as f:

f.write(s)

f.close()

if name == "main":

pool = Pool(10)

for x in range(10):

pool.apply_async(func=run,args=(x,),callback=write_)

pool.close()

pool.join()

可能你觉得会有些慢,这是因为你要写入的数据比较少,启动进程也是需要时间的。

方法二使用文件锁:import multiprocessing

import fcntl

def multi(filepath, fowrite):

"""

多进程入口函数

"""

pool = multiprocessing.Pool(10)

pool.apply_async(multi_take, (fowrite,))

pool.close()

pool.join()

def multi_take(fowrite):

"""

最终结果写入文件(加锁并发写)

"""

with open(fowrite,'a+') as fo:

fcntl.flock(fo.fileno(), fcntl.LOCK_EX) #加锁

fo.write('hello world')

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值