Найти - Пользователи
Полная версия: Multiprocessing и serializing на винде и никсах
Начало » Python для экспертов » Multiprocessing и serializing на винде и никсах
1
Master_Sergius
Здравствуйте,

Начну сразу с кусков кода (это лишь упрощенная симуляция настоящего кода, поэтому не пугайтесь )
Python 3.7-8
 # file process_pe.py 
from concurrent.futures import ALL_COMPLETED, ProcessPoolExecutor, wait
 
from utils import calculate
from manager import get_value
 
 
def main():
    print(get_value())
    print(get_value)
    print('-' * 20)
 
    futures = set()
 
    with ProcessPoolExecutor(max_workers=2) as pool:
        for value in [2, 3]:
            futures.add(pool.submit(calculate, value))
 
            done, futures = wait(futures, return_when=ALL_COMPLETED)
 
            for future in done:
                print(future.result())
 
 
if __name__ == '__main__':
    main()

 # file utils.py
 
import time
from manager import get_value, _test_value
 
 
def calculate(x):
    print('<---')
    get_value()
    print(get_value)
    print('test_value: ', _test_value)
    print(f'id of _test_value: {id(_test_value)}')
    print('--->')
    time.sleep(1)
    return x**x

 # file manager.py
 
_test_value = None
 
 
def get_value():
    global _test_value
    print("Global value:", _test_value)
 
    print('.' * 20)
    print(f'id of _test_value: {id(_test_value)}')
    if not _test_value:
        _test_value = 5
    print('.' * 20)
    return _test_value

Запускаем первый файл (python process_pe.py). На никсах (linux, mac), функция get_value имеет одинаковый id в разных подпроцессах, на винде же get_value имеет разный айдишник. Соответственно, поведение другое. Почему? Проблема в разном создании процессов или сериализации? Как сделать так, чтобы поведение было одинаковым?
Rodegast
> Соответственно, поведение другое. Почему? Проблема в разном создании процессов или сериализации?

Скорее всего это побочный эффект системного вызова fork.

> Как сделать так, чтобы поведение было одинаковым?

Не использовать функцию id
Master_Sergius
Rodegast
Как сделать так, чтобы поведение было одинаковым?Не использовать функцию id
Так дело ж не в id, это вставил для демонстрации/объяснения что и как. А это ведет к проблемам, к примеру с тем значением глобальным (это тоже упрощение, в реальном коде нечто другое)
Rodegast
> А это ведет к проблемам, к примеру с тем значением глобальным

Не волнуйся, проблем не будет.
Master_Sergius
Rodegast
Не волнуйся, проблем не будет.

Ведь получается так, что после десериализации та глобальная переменная на винде получает изначальное значение - None, а на никсах новое - 5, то есть вывод вот здесь разный:
  
 global _test_value
 print("Global value:", _test_value)
Rodegast
> Ведь получается так, что после десериализации та глобальная переменная на винде…

Я надеюсь что ты не изменяешь глобальные переменные в реальных проектах
Master_Sergius
Я таки нашел подверждение своим догадкам - https://stackoverflow.com/questions/49782749/processpoolexecutor-logging-fails-to-log-inside-function-on-windows-but-not-on-u/49791106

Дело таки в процессах, вопрос можно считать закрытым
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB