无法停止线程处理

时间:2019-11-06 02:54:22

标签: python multithreading

我一直在尝试创建一个线程,该线程接受来自其他线程的消息,然后将其写入文件。我的线程看起来像这样:

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信号后立即退出,但打印机线程没有。

0 个答案:

没有答案