Python зависает при доступе к строковому значению в подпроцессе - PullRequest
0 голосов
/ 01 февраля 2019

Я провел почти весь день с этим и пришел к концу моих знаний:

Я хочу изменить общую многопроцессорную обработку. Значение строки в подпроцессе, но Python зависает, как только подпроцесс пытаетсяизменить общее значение.

Ниже приведен пример кода:

from multiprocessing import Process, Value, freeze_support
from ctypes import c_wchar_p

def test(x):
    with x.get_lock():
        x.value = 'THE TEST WORKED'
    return 

if __name__ == "__main__":      
    freeze_support()
    value = Value(c_wchar_p, '')
    p = Process(target=test, args = (value,))
    p.start()
    print(p.pid)
    # this try block is to also allow p.run() 
    try:
            p.join()
            p.terminate()
    except:
            pass
    print(value.value)

То, что я пробовал и не работает:

  • Я пробовал ctypes c_wchar_p иc_char_p, но оба результата приводят к одинаковому замораживанию.
  • Я пробовал также без x.get_lock()
  • Я пробовал также без freeze_support()

Что работает (но не помогает):

  • Использование числа с плавающей запятой в качестве общего значения (value = Value('d',0) и x.value = 1).
  • Запуск процесса без запуска подпроцесса (замените p.start()с p.run())

Я использую 64-битную Windows 10 и Python 3.6.4 (Spyder, но также пробовал вне Spyder).

Любая помощь приветствуется!

1 Ответ

0 голосов
/ 02 февраля 2019

Общий указатель не будет работать в другом процессе, поскольку указатель действителен только в том процессе, в котором он был создан.Вместо этого используйте массив:

import multiprocessing as mp

def test(x):
    x.value = b'Test worked!'

if __name__ == "__main__":      
    x = mp.Array('c',15)
    p = mp.Process(target=test, args = (x,))
    p.start()
    p.join()
    print(x.value)

Вывод:

b'Test worked!'

Обратите внимание, что тип массива 'c' является специализированным и возвращает SynchronizedString против других типов, которые возвращают SynchronizedArray,Вот как использовать тип 'u', например:

import multiprocessing as mp
from ctypes import *

def test(x):
    x.get_obj().value = 'Test worked!'

if __name__ == "__main__":      
    x = mp.Array('u',15)
    p = mp.Process(target=test, args = (x,))
    p.start()
    p.join()
    print(x.get_obj().value)

Выходные данные:

Test worked!

Обратите внимание, что операции с заключенными в нем значениями, не являющимися атомами, такими как +=, выполняютчтение / изменение / запись должны быть защищены с помощью диспетчера контекста with x.get_lock():.

...