首页 > 解决方案 > 在子进程中访问字符串值时 Python 冻结

问题描述

我花了几乎一整天的时间来了解我的知识:

我想更改子进程中的共享 multiprocessing.Value 字符串,但是一旦子进程尝试更改共享值,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)

我尝试过但不起作用:

什么有效(但没有帮助):

我正在使用 Windows 10 64 位和 Python 3.6.4(Spyder,但也在 Spyder 之外尝试过)。

欢迎任何帮助!

标签: python-3.xmultiprocessingsubprocessctypes

解决方案


共享指针在另一个进程中不起作用,因为该指针仅在创建它的进程中有效。相反,使用数组:

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'是专门的,并且返回 aSynchronizedString与返回的其他类型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():上下文管理器进行保护。


推荐阅读