您的位置:

Python 多进程写入同一文件

一、Python 多进程日志写入同一文件

在使用 Python 进行开发时,通常需要记录程序运行过程中的日志信息,而日志写入文件是最常见的方式。在多进程运行的情况下,如果多个进程都要写入同一个文件,就需要考虑并发写入的问题。

解决多进程写入同一文件的方案一般有:

1. 使用共享锁(Lock),让进程互斥的访问文件,避免并发写入。

2. 让所有进程共享一个文件标识符(File Descriptor),通过文件描述符的重定向,实现并发写入。


import logging
from logging.handlers import RotatingFileHandler
import multiprocessing

def worker():
    logger = multiprocessing.get_logger()
    logger.setLevel(logging.INFO)
    
    file_handler = RotatingFileHandler(filename='example.log')
    file_handler.setLevel(logging.INFO)
    
    logger.addHandler(file_handler)
    
    logger.info('Hello, world!')

if __name__ == '__main__':
    logging.basicConfig(filename='example.log')
    logger = multiprocessing.get_logger()
    logger.setLevel(logging.INFO)
    
    processes = []
    for i in range(10):
        p = multiprocessing.Process(target=worker)
        p.start()
        processes.append(p)
    
    for p in processes:
        p.join()

二、Python 多进程读写文件

Python 的 multiprocessing 模块可以很方便的创建多线程和多进程应用。多进程读写文件时,需要注意进程之间的同步问题。

对于一个进程,它打开一个文件后,系统会为它分配一个文件指针,指向文件的开头位置。每次读写文件时,文件指针都会被移动到下一个位置。如果两个进程同时写入一个文件,它们会互相覆盖对方的写入内容,导致数据丢失。因此,需要使用共享锁控制文件写入。


import multiprocessing
import os

def write_file(file_path, data, lock):
    with lock:
        with open(file_path, 'a+') as f:
            f.write(data)        

def read_file(file_path):
    with open(file_path, 'r') as f:
        content = f.read()
    return content

if __name__ == '__main__':
    processes = []
    lock = multiprocessing.Lock()
    for i in range(10):
        p = multiprocessing.Process(target=write_file, args=('example.txt', 'Hello, world!\n', lock))
        p.start()
        processes.append(p)
    
    for p in processes:
        p.join()
    
    content = read_file('example.txt')
    print(content)

三、Python 多进程处理文件

Python 中使用多进程处理文件时,需要避免多个进程同时读写同一个文件,避免数据冲突。一种解决方法是将文件拆分成多个小文件,由每个进程分别处理,最后再将结果组合起来。


import os
import multiprocessing

def process_file(file_path):
    process_id = os.getpid()
    with open(file_path, 'r') as f:
        lines = f.readlines()
    result = [f'Process {process_id}: {line.upper()}' for line in lines]
    
    with open(f'output_{process_id}.txt', 'w') as f:
        f.writelines(result)

if __name__ == '__main__':
    file_path = 'example.txt'
    p1 = multiprocessing.Process(target=process_file, args=(file_path,))
    p2 = multiprocessing.Process(target=process_file, args=(file_path,))
    
    p1.start()
    p2.start()
    
    p1.join()
    p2.join()
    
    with open('output_{}.txt'.format(p1.pid), 'r') as f:
        content1 = f.read()
    with open('output_{}.txt'.format(p2.pid), 'r') as f:
        content2 = f.read()
    
    print(content1 + content2)

四、Python 多进程读取同一个文件

在 Python 中读取同一个文件可以通过 mmap 模块映射到内存中读取,即将文件映射到虚拟内存中,然后将内存中的数据读取出来。


import os
import mmap
import multiprocessing

def process_file(file_path):
    with open(file_path, 'r') as f:
        with mmap.mmap(f.fileno(), length=0, access=mmap.ACCESS_READ) as m:
            content = m.readline()
    return content

if __name__ == '__main__':
    file_path = 'example.txt'
    p1 = multiprocessing.Process(target=process_file, args=(file_path,))
    p2 = multiprocessing.Process(target=process_file, args=(file_path,))
    
    p1.start()
    p2.start()
    
    p1_pid = p1.pid
    p2_pid = p2.pid
    
    p1.join()
    p2.join()
    
    content1 = process_file(file_path)
    content2 = process_file(file_path)
    
    print(f'Process {p1_pid}: {content1}')
    print(f'Process {p2_pid}: {content2}')

五、Python 多进程通信

多进程之间通信可以使用 Python 的 Queue 模块。Queue 支持多线程和多进程,并且线程/进程安全,也支持多个进程同时读写。


import multiprocessing

def producer(queue, data):
    for item in data:
        queue.put(item)

def consumer(queue):
    while True:
        item = queue.get()
        if item is None:
            break
        print(item)

if __name__ == '__main__':
    queue = multiprocessing.Queue()
    
    data = ['a', 'b', 'c', 'd', 'e']
    
    p1 = multiprocessing.Process(target=producer, args=(queue, data))
    p2 = multiprocessing.Process(target=consumer, args=(queue,))
    
    p1.start()
    p2.start()
    
    p1.join()
    
    queue.put(None)
    
    p2.join()

以上就是 Python 多进程写入同一文件的相关内容,包括多进程日志写入同一文件,多进程读写文件,多进程处理文件,多进程读取同一个文件,以及多进程通信等方面。