如何从多进程回调更新全局变量而不覆盖其他作业的值?

22 阅读2分钟

在 Python 中使用多处理库编写 NLP 代码时,遇到了一个问题。我希望能够重置全局变量 paragraph_count,以便在解析完每个文件后将其重置为 0。这个全局变量用作计数器,用于跟踪已解析的段落数。

问题在于,多处理库使用 fork 来创建子进程,每个子进程都有自己的全局变量副本。这意味着如果在一个子进程中更新全局变量,其他子进程不会看到该更改。这导致 paragraph_count 在所有子进程中共享,并且不能单独重置。

2、解决方案:

为了解决这个问题,可以考虑以下几种方法:

1、使用进程间通信(IPC)机制:

可以使用进程间通信(IPC)机制来共享变量,例如使用共享内存或消息队列。这样,每个子进程都可以访问共享变量,并且对共享变量的更改将对所有子进程可见。可以参考以下代码:

import multiprocessing

def worker(shared_variable):
    # Update the shared variable
    shared_variable.value += 1

def main():
    # Create a shared variable
    shared_variable = multiprocessing.Value('i', 0)

    # Create a pool of processes
    pool = multiprocessing.Pool()

    # Apply the worker function to the pool, passing the shared variable as an argument
    pool.apply_async(worker, args=(shared_variable,))

    # Close the pool and wait for all processes to finish
    pool.close()
    pool.join()

    # Print the final value of the shared variable
    print(shared_variable.value)

if __name__ == '__main__':
    main()

2、使用 manager 对象:

manager 对象是多处理库提供的一个类,它允许在进程之间共享变量。manager 对象有自己的内存空间,子进程可以访问 manager 对象中的变量。可以参考以下代码:

import multiprocessing

def worker(manager):
    # Get the shared variable from the manager
    shared_variable = manager.dict()['paragraph_count']

    # Update the shared variable
    shared_variable += 1

def main():
    # Create a manager object
    manager = multiprocessing.Manager()

    # Create a shared variable in the manager
    manager.dict()['paragraph_count'] = 0

    # Create a pool of processes
    pool = multiprocessing.Pool()

    # Apply the worker function to the pool, passing the manager object as an argument
    pool.apply_async(worker, args=(manager,))

    # Close the pool and wait for all processes to finish
    pool.close()
    pool.join()

    # Print the final value of the shared variable
    print(manager.dict()['paragraph_count'])

if __name__ == '__main__':
    main()

3、使用回调函数:

可以考虑使用回调函数来更新全局变量。当一个子进程完成任务时,它可以调用回调函数,在回调函数中更新全局变量。这样,可以避免在子进程中直接更新全局变量,从而防止其他子进程受到影响。可以参考以下代码:

import multiprocessing

def worker(shared_variable):
    # Perform some 작업

    # Call the callback function to update the shared variable
    callback_function(shared_variable)

def callback_function(shared_variable):
    # Update the shared variable
    shared_variable.value += 1

def main():
    # Create a shared variable
    shared_variable = multiprocessing.Value('i', 0)

    # Create a pool of processes
    pool = multiprocessing.Pool()

    # Apply the worker function to the pool, passing the shared variable and callback function as arguments
    pool.apply_async(worker, args=(shared_variable, callback_function))

    # Close the pool and wait for all processes to finish
    pool.close()
    pool.join()

    # Print the final value of the shared variable
    print(shared_variable.value)

if __name__ == '__main__':
    main()

上述方法都可以解决在多处理环境中更新全局变量的问题。您可以根据自己的具体情况选择合适的方法。