multiprocessing.Manager () Семафор против глобальной переменной Семафор - PullRequest
0 голосов
/ 08 ноября 2018

Следующие 2 программы эквивалентны по функциональности (протестировано с python3.5 в Ubuntu 16.04).

Почему предпочтительнее использовать прокси-объект для семафора, возвращаемого Manager (), а не глобальной переменной?

Глобальная переменная:

import multiprocessing as mp
import random
import time

SEMAPHORE = mp.BoundedSemaphore(4)


def main():
    pool = mp.Pool(4)
    for i in range(10):
        SEMAPHORE.acquire()
        pool.apply_async(task, args=(i,), error_callback=log_error)
    pool.close()
    pool.join()


def task(n):
    print('Start: %d' % n)
    time.sleep(0.2 + 0.2 * random.random())
    SEMAPHORE.release()
    print('End: %d' % n)


def log_error(exception):
    print('Got error: %s' % exception)


if __name__ == '__main__':
    main()

Объект прокси от Manager ()

import multiprocessing as mp
import random
import time


def main():
    with mp.Manager() as manager:
        semaphore = manager.BoundedSemaphore(4)
        pool = mp.Pool(4)
        for i in range(10):
            semaphore.acquire()
            pool.apply_async(task, args=(semaphore, i), error_callback=log_error)
        pool.close()
        pool.join()


def task(sem, n):
    print('_Start: %d' % n)
    time.sleep(0.2 + 0.2 * random.random())
    sem.release()
    print('_End: %d' % n)


def log_error(exception):
    print('Got error: %s' % exception)


if __name__ == '__main__':
    main()
...