2

Python 3.1.2

multiprocessing.Processによって生成された2つのスレッド間の変数共有に問題があります。これは単純なbool変数であり、スレッドを実行するか、実行を停止するかを決定する必要があります。以下は、3つのケースで示されている簡略化されたコードです(ただし、元のコードと同じメカニズムを使用しています)。

  1. threading.Threadタイプとself.is_runningboolタイプのメインクラスのビーイング[正常に動作します]。
  2. multiprocess.Processタイプとself.is_runningboolタイプのメインクラスbeeing[動作していません。子スレッドには、共有する代わりにself.is_runningのローカルコピーがあります]。
  3. multiprocess.Processタイプのメインクラスbeeingとself.is_runningは、multiprocessing.Value( "b"、True)タイプです[正常に動作します]。

私が欲しいのは、なぜそれがこのように機能し、他の方法では機能しないのかを理解することです。(つまり、ポイント2が想定どおりに機能しない理由)。

テストはPythonのインタプリタから行われます。

from testclass import *

d = TestClass()
d.start()
d.stop()

以下はポイント1の例です。

import threading
import time
import queue
import multiprocessing

class TestClass(threading.Thread):
def __init__(self):
    threading.Thread.__init__(self)
    self.q = queue.Queue(10)
    self.is_running = True
    self.sema = threading.Semaphore()

def isRunning(self):
    self.sema.acquire()
    print ("Am I running?", self.is_running)
    z = self.is_running
    self.sema.release()
    return z

def stop(self):
    self.sema.acquire()
    self.is_running = False
    print("STOPPING")
    self.sema.release()

def reader(self):
    while self.isRunning():
        print("R] Reading!")
        try:
            data = self.q.get(timeout=1)
        except:
            print("R] NO DATA!")
        else:
            print("R] Read: ", data)
def writer(self):
    while self.isRunning():
        print("W] Writing!")
        self.q.put(time.time())
        time.sleep(2)

def run(self):
    tr = threading.Thread(target=self.reader)
    tw = threading.Thread(target=self.writer)
    tr.start()
    tw.start()
    tr.join()
    tw.join()

ポイント2の例:

import threading
import time
import queue
import multiprocessing


class Test(multiprocessing.Process):
def __init__(self):
    multiprocessing.Process.__init__(self)
    self.q = queue.Queue(10)
    self.is_running = True
    self.sema = threading.Semaphore()

def isRunning(self):
    self.sema.acquire()
    print ("Am I running?", self.is_running)
    z = self.is_running
    self.sema.release()
    return z

def stop(self):
    self.sema.acquire()
    self.is_running = False
    print("STOPPING")
    self.sema.release()

def reader(self):
    while self.isRunning():
        print("R] Reading!")
        try:
            data = self.q.get(timeout=1)
        except:
            print("R] NO DATA!")
        else:
            print("R] Read: ", data)
def writer(self):
    while self.isRunning():
        print("W] Writing!")
        self.q.put(time.time())
        time.sleep(2)

def run(self):
    tr = threading.Thread(target=self.reader)
    tw = threading.Thread(target=self.writer)
    tr.start()
    tw.start()
    tr.join()
    tw.join()

ポイント3の例:

import threading
import time
import queue
import multiprocessing

class TestClass(multiprocessing.Process):
def __init__(self):
    multiprocessing.Process.__init__(self)
    self.q = queue.Queue(10)
    self.is_running = multiprocessing.Value("b", True)
    self.sema = threading.Semaphore()

def isRunning(self):
    self.sema.acquire()
    print ("Am I running?", self.is_running)
    z = self.is_running.value
    self.sema.release()
    return z

def stop(self):
    self.sema.acquire()
    self.is_running.value = False
    print("STOPPING")
    self.sema.release()

def reader(self):
    while self.isRunning():
        print("R] Reading!")
        try:
            data = self.q.get(timeout=1)
        except:
            print("R] NO DATA!")
        else:
            print("R] Read: ", data)
def writer(self):
    while self.isRunning():
        print("W] Writing!")
        self.q.put(time.time())
        time.sleep(2)

def run(self):
    tr = threading.Thread(target=self.reader)
    tw = threading.Thread(target=self.writer)
    tr.start()
    tw.start()
    tr.join()
    tw.join()
4

2 に答える 2

0

ポイント 2 では、親プロセスと子プロセスの両方に独自の のコピーがありis_runningます。親プロセスで呼び出すstop()と、親プロセスでのみ変更is_runningされ、子プロセスでは変更されません。multiprocessing.Valueが機能する理由は、そのメモリが両方のプロセス間で共有されているためです。

プロセス対応のキューが必要な場合は、multiprocessing.Queueを使用します。

于 2012-07-03T16:15:36.767 に答える
0

スレッドはすべて同じプロセスの一部であるため、メモリを共有します。別の結果として、プロセスは 1 つの cpu によってのみ取得できるため、異なる cpu によってスレッドを正確に同時に実行することはできません。

プロセスには個別のメモリ空間があります。1 つの CPU が 1 つのプロセスを実行すると同時に、別の CPU が別のプロセスを実行できます。プロセスを協調させるには、特別な構造が必要です。

于 2012-07-03T10:43:55.583 に答える