python-全局变量

python-全局变量,python,python-multithreading,Python,Python Multithreading,我发现了一个关于队列和线程的Python教程。代码如下: #!/usr/bin/python import Queue import threading import time exitFlag = 0 class myThread (threading.Thread): def __init__(self, threadID, name, q): threading.Thread.__init__(self) self.threadID = thr

我发现了一个关于队列和线程的Python教程。代码如下:

#!/usr/bin/python

import Queue
import threading
import time

exitFlag = 0

class myThread (threading.Thread):
    def __init__(self, threadID, name, q):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.q = q
    def run(self):
        print "Starting " + self.name
        process_data(self.name, self.q)
        print "Exiting " + self.name

def process_data(threadName, q):
    while not exitFlag:
        queueLock.acquire()
        if not workQueue.empty():
            data = q.get()
            queueLock.release()
            print "%s processing %s" % (threadName, data)
            time.sleep(3)
            print "%s finished processing %s" % (threadName, data)
        else:
            queueLock.release()
        time.sleep(1)


threadList = ["Thread-1", "Thread-2", "Thread-3"]
nameList = ["One", "Two", "Three", "Four", "Five"]
queueLock = threading.Lock()
workQueue = Queue.Queue(10)
threads = []
threadID = 1

# Create new threads
for tName in threadList:
    thread = myThread(threadID, tName, workQueue)
    thread.start()
    threads.append(thread)
    threadID += 1


# Fill the queue
queueLock.acquire()
for word in nameList:
    workQueue.put(word)
queueLock.release()

# Wait for queue to empty
while not workQueue.empty():
    pass

# Notify threads it's time to exit
exitFlag = 1

# Wait for all threads to complete
for t in threads:
    t.join()
print "Exiting Main Thread"
我是Python和线程+队列的新手,请原谅

我打算编写几个线程类(例如:myThread1、myThread2等)。在main()中,它将接收命令行参数并决定创建哪个线程类

所以我想把myThread类和main拆分成一个单独的python文件。我还打算将process_data方法移动到myThread类中,以执行一组规则,这些规则对于每个thread类都是不同的。将其视为封装

这就是我尝试过的:

mythread.py:

#!/usr/bin/python

import Queue
import threading
import time

exitFlag = 0

class myThread (threading.Thread):
    def __init__(self, threadID, name, q):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.q = q
    def run(self):
        print "Starting " + self.name
        process_data(self.name, self.q)
        print "Exiting " + self.name

def process_data(threadName, q):
    while not exitFlag:
        queueLock.acquire()
        if not workQueue.empty():
            data = q.get()
            queueLock.release()
            print "%s processing %s" % (threadName, data)
            time.sleep(3)
            print "%s finished processing %s" % (threadName, data)
        else:
            queueLock.release()
        time.sleep(1)
main.py

threadList = ["Thread-1", "Thread-2", "Thread-3"]
nameList = ["One", "Two", "Three", "Four", "Five"]
queueLock = threading.Lock()
workQueue = Queue.Queue(10)
threads = []
threadID = 1

# Create new threads
for tName in threadList:
    thread = myThread(threadID, tName, workQueue)
    thread.start()
    threads.append(thread)
    threadID += 1


# Fill the queue
queueLock.acquire()
for word in nameList:
    workQueue.put(word)
queueLock.release()

# Wait for queue to empty
while not workQueue.empty():
    pass

# Notify threads it's time to exit
exitFlag = 1

# Wait for all threads to complete
for t in threads:
    t.join()
print "Exiting Main Thread"
from mythread import MyThread
import Queue
import threading

threadList = ["Thread-1", "Thread-2", "Thread-3"]
nameList = ["One", "Two", "Three", "Four", "Five"]
workQueue = Queue.Queue(10)
threads = []
threadID = 1

# Create new threads
for tName in threadList:
    thread = MyThread(threadID, tName, workQueue)
    thread.start()
    threads.append(thread)
    threadID += 1

# Fill the queue
for word in nameList:
    workQueue.put(word)

# Wait for queue to empty
while not workQueue.empty():
    pass

# Notify threads it's time to exit
for t in threads:
    t.stop()

# Wait for all threads to complete
for t in threads:
    t.join()
print "Exiting Main Thread"
我现在面临几个问题:

  • 如何将exitFlag传递给myThread类?我尝试将其设置为类变量,但当我在main中设置
    exitFlag=1
    时,whilenotexitflag将永远不会为真
  • 如何将queueLock传递到类中?这里也一样。现在它被声明为全局变量?如果我将它设置为myThread的成员变量,它也不起作用

  • 从main.py导入您的线程类,并从main.py执行您想要的任何操作。不要执行mythread.py,然后让线程检查exitFlag并从main.py更改它。

    对#1的回答是不要使用全局变量。相反,在
    myThread
    子类中添加一个标志

    至于问题#2,
    队列
    类是为多线程编程而设计的,因此它的方法会自动为您处理所有需要的锁定细节,从而防止同时访问问题。这意味着您实际上不需要
    queueLock

    将这两个建议合并到您的答案中会产生如下结果(未经测试):

    main.py

    threadList = ["Thread-1", "Thread-2", "Thread-3"]
    nameList = ["One", "Two", "Three", "Four", "Five"]
    queueLock = threading.Lock()
    workQueue = Queue.Queue(10)
    threads = []
    threadID = 1
    
    # Create new threads
    for tName in threadList:
        thread = myThread(threadID, tName, workQueue)
        thread.start()
        threads.append(thread)
        threadID += 1
    
    
    # Fill the queue
    queueLock.acquire()
    for word in nameList:
        workQueue.put(word)
    queueLock.release()
    
    # Wait for queue to empty
    while not workQueue.empty():
        pass
    
    # Notify threads it's time to exit
    exitFlag = 1
    
    # Wait for all threads to complete
    for t in threads:
        t.join()
    print "Exiting Main Thread"
    
    from mythread import MyThread
    import Queue
    import threading
    
    threadList = ["Thread-1", "Thread-2", "Thread-3"]
    nameList = ["One", "Two", "Three", "Four", "Five"]
    workQueue = Queue.Queue(10)
    threads = []
    threadID = 1
    
    # Create new threads
    for tName in threadList:
        thread = MyThread(threadID, tName, workQueue)
        thread.start()
        threads.append(thread)
        threadID += 1
    
    # Fill the queue
    for word in nameList:
        workQueue.put(word)
    
    # Wait for queue to empty
    while not workQueue.empty():
        pass
    
    # Notify threads it's time to exit
    for t in threads:
        t.stop()
    
    # Wait for all threads to complete
    for t in threads:
        t.join()
    print "Exiting Main Thread"
    
    mythread.py

    import threading
    import time
    
    class MyThread (threading.Thread):  # note capitalization change
        def __init__(self, threadID, name, q):
            threading.Thread.__init__(self)
            self.threadID = threadID
            self.name = name
            self.q = q
            self.__exitFlag = False
            self.__signal_lock = threading.Lock()
        def run(self):
            print "Starting " + self.name
            self.process_data()
            print "Exiting " + self.name
        def stop(self):
            with self.__signal_lock:
                self.__exitFlag = True
        def process_data(self):
            while not self.__exitFlag:
                if not self.q.empty():
                    data = self.q.get()
                    print "%s processing %s" % (self.name, data)
                    time.sleep(3)
                    print "%s finished processing %s" % (self.name, data)
                time.sleep(1)
    

    这是有效的解决办法

    mythread_class.py

    import threading
    import time
    
    class MyThread (threading.Thread):
        def __init__(self, threadID, threadname, q):
            threading.Thread.__init__(self)
            self.threadID = threadID
            self.threadname = threadname
            self.queue = q
            self.__exitFlag = False
            self.__signal_lock = threading.Lock()
    
        def run(self):
            print "Starting " + self.threadname
            self.process_data()
            print "Exiting " + self.threadname
    
        def stop(self):
            with self.__signal_lock:
                self.__exitFlag = True
    
        def process_data(self):
            while not self.__exitFlag:
                if not self.queue.empty():
                    data = self.queue.get()
                    print "%s processing %s" % (self.threadname, data)
                    time.sleep(3)
                    print "%s finished processing %s" % (self.threadname, data)
    
                time.sleep(1)
    
    main.py 从mythread\u类导入mythread 导入队列 导入线程

    threadList = ["Thread-1", "Thread-2", "Thread-3"]
    nameList = ["One", "Two", "Three", "Four", "Five"]
    workQueue = Queue.Queue(10)
    threads = []
    threadID = 1
    
    # Create new threads
    for tName in threadList:
        thread = MyThread(threadID, tName, workQueue)
        thread.start()
        threads.append(thread)
        threadID += 1
    
    # Fill the queue
    for word in nameList:
        workQueue.put(word)
    
    # Wait for queue to empty
    while not workQueue.empty():
        pass
    
    # Notify threads it's time to exit
    for t in threads:
        t.stop()
    
    # Wait for all threads to complete
    for t in threads:
        t.join()
    print "Exiting Main Thread"
    
    如果您有多个MyThread类,只需将此行替换为其他类:

    thread = MyThread(threadID, tName, workQueue)
    
    --或--


    您好,谢谢您的解决方案。它就像一个符咒。不过,对您的代码进行了一次更正(在MyThread中,将workQueue替换为self.q)。哦,错过了一次——很高兴能提供帮助。你好,martineau,我回来了。我发现有必要添加queueLock。如果没有它,我的程序将不会退出主线程,如果我有比队列项目更多的线程。不清楚为什么你会有比队列项目更多的线程(不包括主线程)。无论如何,可以通过预先设置其属性(其默认初始值从创建线程继承),使已启动的线程对象不阻止主线程退出。在我的答案中的代码中,可以通过向
    MyThread.\uuuu init\uuuu()
    构造函数方法添加
    self.daemon=True
    语句来实现。