Уведомления

Группа в Telegram: @pythonsu

#1 Июнь 12, 2020 15:13:32

Master_Sergius
Зарегистрирован: 2013-09-12
Сообщения: 271
Репутация: +  7  -
Профиль   Отправить e-mail  

Multiprocessing и serializing на винде и никсах

Здравствуйте,

Начну сразу с кусков кода (это лишь упрощенная симуляция настоящего кода, поэтому не пугайтесь )
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 имеет разный айдишник. Соответственно, поведение другое. Почему? Проблема в разном создании процессов или сериализации? Как сделать так, чтобы поведение было одинаковым?



———————————————————————————
Мой блог о семействе *nix: http://nixtravelling.blogspot.com/

Отредактировано Master_Sergius (Июнь 12, 2020 15:14:08)

Офлайн

#2 Июнь 12, 2020 15:56:27

Rodegast
От: Пятигорск
Зарегистрирован: 2007-12-28
Сообщения: 2679
Репутация: +  182  -
Профиль   Отправить e-mail  

Multiprocessing и serializing на винде и никсах

> Соответственно, поведение другое. Почему? Проблема в разном создании процессов или сериализации?

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

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

Не использовать функцию id



С дураками и сектантами не спорю, истину не ищу.
Ели кому-то правда не нравится, то заранее извиняюсь.

Онлайн

#3 Июнь 12, 2020 16:47:48

Master_Sergius
Зарегистрирован: 2013-09-12
Сообщения: 271
Репутация: +  7  -
Профиль   Отправить e-mail  

Multiprocessing и serializing на винде и никсах

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



———————————————————————————
Мой блог о семействе *nix: http://nixtravelling.blogspot.com/

Офлайн

#4 Июнь 12, 2020 17:38:21

Rodegast
От: Пятигорск
Зарегистрирован: 2007-12-28
Сообщения: 2679
Репутация: +  182  -
Профиль   Отправить e-mail  

Multiprocessing и serializing на винде и никсах

> А это ведет к проблемам, к примеру с тем значением глобальным

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



С дураками и сектантами не спорю, истину не ищу.
Ели кому-то правда не нравится, то заранее извиняюсь.

Онлайн

#5 Июнь 12, 2020 18:15:54

Master_Sergius
Зарегистрирован: 2013-09-12
Сообщения: 271
Репутация: +  7  -
Профиль   Отправить e-mail  

Multiprocessing и serializing на винде и никсах

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

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



———————————————————————————
Мой блог о семействе *nix: http://nixtravelling.blogspot.com/

Отредактировано Master_Sergius (Июнь 12, 2020 18:16:04)

Офлайн

#6 Июнь 13, 2020 00:52:39

Rodegast
От: Пятигорск
Зарегистрирован: 2007-12-28
Сообщения: 2679
Репутация: +  182  -
Профиль   Отправить e-mail  

Multiprocessing и serializing на винде и никсах

> Ведь получается так, что после десериализации та глобальная переменная на винде…

Я надеюсь что ты не изменяешь глобальные переменные в реальных проектах



С дураками и сектантами не спорю, истину не ищу.
Ели кому-то правда не нравится, то заранее извиняюсь.

Онлайн

#7 Июнь 13, 2020 17:42:27

Master_Sergius
Зарегистрирован: 2013-09-12
Сообщения: 271
Репутация: +  7  -
Профиль   Отправить e-mail  

Multiprocessing и serializing на винде и никсах

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

Дело таки в процессах, вопрос можно считать закрытым



———————————————————————————
Мой блог о семействе *nix: http://nixtravelling.blogspot.com/

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version