Python多个线程访问同一文件

13

我有两个线程,一个用于写文件,另一个定期将文件移动到不同的位置。写入操作总是在写入消息前调用open,并在写入消息后调用close。移动操作使用shutil.move进行移动。

我发现在第一次移动之后,写入线程无法再向文件中写入任何内容,即第一次移动后文件的大小始终为0。我是否做错了什么?

3个回答

29

锁定是一种可能的解决方案,但我更喜欢每个外部资源(包括文件)由单独的线程处理的通用架构。其他线程将工作请求发送到专用线程上的 Queue.Queue 实例(并在工作请求的参数中提供自己的独立队列,如果需要结果返回),专用线程大部分时间都在等待该队列上的 .get,每当它获得请求时就会继续执行它(如果需要,在传入的队列上返回结果)。

我在《Python in a Nutshell》等书中提供了详细的示例。Python的Queue本质上是线程安全的,并极大地简化了您的生活。

这种架构的优点之一是,如果您决定将一些工作切换到单独的进程而不是单独的线程(例如利用多个核心),则可以平稳地转换到multiprocessing -- multiprocessing 提供其自己的类似于 Queue 类型的功能,使这种转换顺畅如丝般顺滑;-)。


如果我正在编写一个应该是线程安全的库,但不总是在线程中使用。我应该采取这种方法还是考虑加锁?我不确定如果我的库只被一个线程使用,它是否应该生成新线程。对于一个可变数量的线程可能只有一个的情况,什么是最好的解决方案? 应该采取哪种方法或者考虑加锁?对于可能只有一个线程的情况,最佳解决方案是什么? - Luke Taylor

8

当两个线程访问同一资源时,会发生奇怪的事情。为了避免这种情况,应始终锁定资源。Python提供了方便的threading.Lock方法来实现这个目的,同时还有其他工具(请参阅threading模块的文档)。


4

你确定这可以与移动文件结合使用吗? - Eli Bendersky
3
Evan Fosmark的代码适用于同步多个“进程”,而不是“线程”。根据Eli的建议,我会使用threading.Lockthreading.RLock - Vinay Sajip
作为跟进,此帖子中的链接已不再有效。根据Evan在这里回答相关问题的答案,您也可以在https://github.com/dmfrey/FileLock找到代码。 - MartyMacGyver

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接