3

Python でマルチプロセッシングを実験しており、2 つのプロセス間で文字列の配列を共有しようとしました。ここに私のpythonコードがあります:

from multiprocessing import Process, Array, Value
import ctypes

def f1(a, v):
    for i, l in enumerate(['a', 'b', 'c']):
        a[i] = l*3

    v.value += 1

    print "f1 : ", a[:], v.value

def f2(a,v):

    v.value += 1

    print "f2 : ", a[:], v.value

if __name__ == '__main__':
    val = Value(ctypes.c_int, 0)
    arr = Array(ctypes.c_char_p, 3)

    print "Before :", arr[:], val.value

    p = Process(target=f1, args=(arr, val))
    p2 = Process(target=f2, args=(arr, val))

    p.start()
    p2.start()

    p.join()
    p2.join()

    print "After : ", arr[:], val.value

スクリプトを実行すると、arr正しく設定されており、 では利用可能ですが、 では利用できf1()ないことがわかりますf2()。結果は次のとおりです。

    % python /tmp/tests.py
    Before : [None, None, None] 0
    f1 :  ['aaa', 'bbb', 'ccc'] 1
    f2 :  ['\x01', '\x11', '\x01'] 2
    After :  ['\x01', '\x01', '\x01'] 2

私は何かを見落としましたか?

フィードバックをお寄せいただきありがとうございます。:)

4

2 に答える 2

3

私の推測は次のとおりです。

arr3 つのポインターを格納します。f1()現在のプロセスの外では意味のないメモリアドレスにそれらを割り当てます。f2()この時点で、ジャンクを含む無意味なアドレスにアクセスしようとします。

すべてのプロセスで意味を持つ値に割り当てると、次のように役立ちます。

from __future__ import print_function
import ctypes
import time
from multiprocessing import Process, Array, Value

values = [(s*4).encode('ascii') for s in 'abc']

def f1(a, v):
    for i, s in enumerate(values):
        a[i] = s

    v.value += 1

    print("f1 : ", a[:], v.value)

def f2(a,v):
    v.value += 1
    print("f2 : ", a[:], v.value)

def main():
    val = Value(ctypes.c_int, 0)
    arr = Array(ctypes.c_char_p, 3)

    print("Before :", arr[:], val.value)

    p = Process(target=f1, args=(arr, val))
    p2 = Process(target=f2, args=(arr, val))

    p.start()
    p2.start()

    p.join()
    p2.join()

    print("After : ", arr[:], val.value)

if __name__ == '__main__':
    main()

出力

Before : [None, None, None] 0
f1 :  ['aaaa', 'bbbb', 'cccc'] 1
f2 :  ['aaaa', 'bbbb', 'cccc'] 2
After :  ['aaaa', 'bbbb', 'cccc'] 2
于 2012-08-07T15:20:11.610 に答える
0

解決策はありませんが、ヒントを追加できます。問題を特定するためにスクリプトを削除しました。問題はl * 3操作にあるように私には見えます。理由はわかりませんが、期待どおりに動作するようにl * 3操作を移動します。enumerator

from multiprocessing import Process, Array                                   
import ctypes                                                                


def f1(a):                                                                   
#    for i, l in enumerate(['a', 'b', 'c']):                                 
#        a[i] = (l * 3)                                                      
    for i, l in enumerate(['a' * 3, 'b' * 3, 'c' * 3]):                      
        a[i] = l                                                             

    print "f1 : ", map(id, a), a[:]                                          


if __name__ == '__main__':                                                   
    arr = Array(ctypes.c_char_p, 3)                                          

    print "Before :", map(id, arr), arr[:]                                   
    p = Process(target=f1, args=(arr, ))                                     
    p.start()                                                                
    p.join()                                                                 
    print "After : ", map(id, arr), arr[:]                                   

結果:

Before : [3077673516L, 3077673516L, 3077673516L] [None, None, None]
f1 :  [3073497784L, 3073497784L, 3073497784L] ['aaa', 'bbb', 'ccc']
After :  [3073497784L, 3073497784L, 3073497784L] ['aaa', 'bbb', 'ccc']
于 2012-08-07T15:49:32.120 に答える