1

私はPythonでスレッドをいじっているだけで、Pythonもまったく初めてです。スレッドを作成するプロデューサー クラスがあります。これらのスレッドはすべて、共通リソースである単一のオブジェクトにアクセスします。以下はコードです

class Producer (threading.Thread):
    def __init__(self, threadId, source):
    threading.Thread.__init__(self)
    self.source = source
    self.threadId = threadId

    def produce(self):
    while 1:
        data = self.source.getData()
        if data == False:
            print "===== Data finished for "+self.threadId+" ====="
            break
        else:
            print data

    def run(self):
        self.produce()
#class

class A:
    def __init__(self):
        self.dataLimit = 5
        self.dataStart = 1

    def getData(self):
        lock = Lock()
        lock.acquire()
        if self.dataStart > self.dataLimit:
           return False
        lock.release()

        data = "data from A :: "+str(self.dataStart)+" Accessor thread :: "+thread.threadId
        time.sleep(0.5)

        lock.acquire()
        self.dataStart += 1
        lock.release()

        return data
   #def
#class

source = A()
for i in range(2):
    thread = Producer( "t_producer"+str(i), source )
    thread.start()


print "Main thread exiting..."

したがって、クラス A は dataStart を 1 から 5 までカウントします。これは共通のリソースであり、getData メソッドもロックを実装しているため、プロデューサー クラスのスレッドは getData メソッドに交互にアクセスし、予想される出力は次のようになります。

data from A :: 1 Accessor thread :: t_producer0
data from A :: 2 Accessor thread :: t_producer1
data from A :: 3 Accessor thread :: t_producer1
data from A :: 4 Accessor thread :: t_producer0
data from A :: 5 Accessor thread :: t_producer0
===== Data finished for t_producer0 =====
===== Data finished for t_producer1 =====

しかし、私はこれを得ています:

data from A :: 1 Accessor thread :: t_producer0
data from A :: 1 Accessor thread :: t_producer1
data from A :: 3 Accessor thread :: t_producer1
data from A :: 3 Accessor thread :: t_producer1
data from A :: 5 Accessor thread :: t_producer1
===== Data finished for t_producer0 =====
data from A :: 5 Accessor thread :: t_producer1
===== Data finished for t_producer1 =====

データ カウントが繰り返されていることがわかるように、ランダム カウントが欠落しています。ここでこの問題に対処するにはどうすればよいですか?

4

2 に答える 2

4
def getData(self):
    lock = Lock()
    lock.acquire()
    if self.dataStart > self.dataLimit:
       return False
    lock.release()

    data = "data from A :: "+str(self.dataStart)+" Accessor thread :: "+thread.threadId
    time.sleep(0.5)

リリース呼び出しの前に False を返しています。with次のようにステートメントを使用してみてください。

with lock:
    # Do stuff

これにより、確実に取得してからリリースすることができます。

于 2012-11-27T19:24:12.490 に答える
-1
def getData(self):
        lock = threading.Lock()
        with lock:
            if self.dataStart > self.dataLimit:
                return False

            data = "data from A :: " + str(self.dataStart) + " Accessor thread :: " + thread.threadId
            self.dataStart += 1
        return data
于 2015-06-17T12:08:51.113 に答える