我一直在尝试创建一个线程,该线程接受来自其他线程的消息,然后将其写入文件。我的线程看起来像这样:
class SharedFilePrinter(threading.Thread):
printQueue = None
initDone = False
def __init__(self, printQueue, filePath, fileMode = 'a'):
threading.Thread.__init__(self)
self.running = True
self.openFile(printQueue, filePath, fileMode)
def openFile(self, printQueue, filePath, fileMode = 'a'):
if not self.initDone:
try:
dirPath = os.path.dirname(filePath)
if not os.path.exists(dirPath):
os.mkdir(dirPath)
self.outFile = open(filePath, fileMode)
self.printQueue = printQueue
self.initDone = True
print("started Printer thread")
except:
print("? Unable to open file", filePath)
self.initDone = False
def stop(self):
self.running = False
def isRunning(self):
return self.running
def run(self):
while True:
if self.initDone:
msg = self.printQueue.get()
# self.outFile.write(msg)
self.printQueue.task_done()
if not self.running:
break
if self.initDone:
self.outFile.close()
print("Exiting Printer Thread")
我正在调用THREAD_OBJ.stop()
来停止线程,并等待使用THREAD_OBJ.join()
退出线程。打印机线程从不从run()
函数返回。测试代码如下:
#!/sur/bin/python
import queue
import sys, os
import threading
import time
class SharedFilePrinter(threading.Thread):
printQueue = None
initDone = False
def __init__(self, printQueue, filePath, fileMode = 'a'):
threading.Thread.__init__(self)
self.running = True
self.openFile(printQueue, filePath, fileMode)
def openFile(self, printQueue, filePath, fileMode = 'a'):
if not self.initDone:
try:
dirPath = os.path.dirname(filePath)
if not os.path.exists(dirPath):
os.mkdir(dirPath)
self.outFile = open(filePath, fileMode)
self.printQueue = printQueue
self.initDone = True
print("started Printer thread")
except:
print("? Unable to open file", filePath)
self.initDone = False
def stop(self):
self.running = False
def isRunning(self):
return self.running
def run(self):
while True:
if self.initDone:
msg = self.printQueue.get()
# self.outFile.write(msg)
self.printQueue.task_done()
if not self.running:
break
if self.initDone:
self.outFile.close()
print("Exiting Printer Thread")
# Commands #
# start : Prints random number every second
# echo <String> : Echo the message (Everything after the word 'Echo')
# stop : Stop printing random numbers
class ProcessThread(threading.Thread):
def __init__(self, instrQueue, printQueue, index):
threading.Thread.__init__(self)
self.running = True
self.printNumber = False
self.index = index
self.instrQueue = instrQueue
self.printQueue = printQueue
self.number = 0
print("started Thread", self.index)
def commandProcessor(self, command):
cmdWords = command.split()
currentIndex = 0
numCmdWords = len(cmdWords)
while (currentIndex < numCmdWords):
currentCmd = cmdWords[currentIndex].lower()
if (currentCmd == "start"):
self.printNumber = True
currentIndex += 1
elif (currentCmd == "stop"):
self.printNumber = False
currentIndex += 1
elif (currentCmd == "echo"):
if ((currentIndex + 1) < numCmdWords):
msg = "Echo from {id}".format(id=str(self.index)) + " ".join(cmdWords[currentIndex+1:])
self.printQueue.put(msg)
print(msg)
currentIndex = numCmdWords
def run(self):
while True:
if not self.instrQueue.empty():
insrt = self.instrQueue.get()
self.commandProcessor(insrt)
self.instrQueue.task_done()
if self.printNumber:
msg = "Thread {id}: {val}".format(id=str(self.index), val=str(self.number))
self.printQueue.put(msg)
print(msg)
self.number+=1
time.sleep(0.5)
if not self.running:
break
print("Exiting thread:", self.index)
def stop(self):
self.running = False
def isRunning(self):
return self.running
if __name__ == "__main__":
cmdQueues = [queue.Queue() for i in range(3)]
printQueue = queue.Queue()
workers = [ProcessThread(cmdQueues[i], printQueue, i) for i in range(3)]
for i in range(3):
workers[i].start()
p = SharedFilePrinter(printQueue, './log.txt')
p.start()
printQueue.put("Test Printer")
for i in range(3):
cmdQueues[i].put("start echo START Running")
time.sleep(2)
for i in range(3):
cmdQueues[i].put("stop echo STOP Running")
for i in range(3):
cmdQueues[i].join()
workers[i].stop()
printQueue.join()
p.stop()
for i in range(3):
workers[i].join()
print("Joined", i)
while not p.join(1):
print(p.is_alive())
print("Joined Print")
工作线程在收到stop
信号后立即退出,但打印机线程没有。