0

後でプロットする関数のデータ ポイントを生成するプログラムを作成しました。このプログラムは、関数を定義するクラスを取り、呼び出されたときにデータをテキスト ファイルに生成するデータ出力オブジェクトを作成します。プロセス全体を高速化するためにジョブをスレッドに入れましたが、そうすると、生成されるデータが常に正しいとは限りません。私が何を意味するかを示すために写真を添付し​​ました:

データプロット

関連するコードの一部を次に示します。

from queue import Queue
import threading
import time

queueLock = threading.Lock()
workQueue = Queue(10) 

def process_data(threadName, q, queue_window, done):
    while not done.get():
        queueLock.acquire()         # check whether or not the queue is locked
        if not workQueue.empty():
            data = q.get()
            # data is the Plot object to be run
            queueLock.release()
            data.parent_window = queue_window
            data.process()
        else:
            queueLock.release()
        time.sleep(1)

class WorkThread(threading.Thread):
    def __init__(self, threadID, q, done):
        threading.Thread.__init__(self)
        self.ID = threadID
        self.q = q
        self.done = done
    def get_qw(self, queue_window):
        # gets the queue_window object
        self.queue_window = queue_window
    def run(self):
        # this is called when thread.start() is called
        print("Thread {0} started.".format(self.ID))
        process_data(self.ID, self.q, self.queue_window, self.done)
        print("Thread {0} finished.".format(self.ID))

class Application(Frame):
    def __init__(self, etc):
        self.threads = []
        # does some things
    def makeThreads(self):
        for i in range(1, int(self.threadNum.get()) +1):
            thread = WorkThread(i, workQueue, self.calcsDone)
            self.threads.append(thread)
    # more code which just processes the function etc, sorts out the gui stuff.

そして、別のクラスで(私はtkinterを使用しているため、スレッドを実行するための実際のコードは別のウィンドウで呼び出されます)(self.parentはApplicationクラスです):

    def run_jobs(self):
        if self.running == False:
            # threads are only initiated when jobs are to be run
            self.running = True
            self.parent.calcsDone.set(False)
            self.parent.threads = []        # just to make sure that it is initially empty, we want new threads each time
            self.parent.makeThreads()
            self.threads = self.parent.threads

            for thread in self.threads:
                thread.get_qw(self)
                thread.start()

            # put the jobs in the workQueue
            queueLock.acquire()
            for job in self.job_queue:
                workQueue.put(job)
            queueLock.release()
        else:
            messagebox.showerror("Error", "Jobs already running")

これは、スレッドに関連するすべてのコードです。複数のスレッドでプログラムを実行すると、一部のデータポイントが正しくないのに、単一のスレッドで実行するとデータがすべて完璧になる理由がわかりません。「スレッドセーフ」なプロセスを調べてみましたが、何も見つかりませんでした。

前もって感謝します!

4

0 に答える 0