後でプロットする関数のデータ ポイントを生成するプログラムを作成しました。このプログラムは、関数を定義するクラスを取り、呼び出されたときにデータをテキスト ファイルに生成するデータ出力オブジェクトを作成します。プロセス全体を高速化するためにジョブをスレッドに入れましたが、そうすると、生成されるデータが常に正しいとは限りません。私が何を意味するかを示すために写真を添付しました:
関連するコードの一部を次に示します。
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")
これは、スレッドに関連するすべてのコードです。複数のスレッドでプログラムを実行すると、一部のデータポイントが正しくないのに、単一のスレッドで実行するとデータがすべて完璧になる理由がわかりません。「スレッドセーフ」なプロセスを調べてみましたが、何も見つかりませんでした。
前もって感謝します!