python - 全局变量

时间:2014-07-03 15:03:21

标签: 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 = 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类中,以执行一组规则,这些规则对于每个线程类都是不同的。把它想象成封装。

这就是我的尝试:

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"

我现在面临一些问题:

  1. 如何将exitFlag传递给myThread类?我尝试将其设置为类变量,但是当我在main
  2. 中设置while not exitFlag时,exitFlag=1永远不会成立
  3. 如何将queueLock传递给类?同样的事情在这里现在它被声明为全局变量?如果我将它设置为myThread的成员变量,它也无法工作。

3 个答案:

答案 0 :(得分:1)

从main.py导入你的线程类并从main.py执行你想要的任何东西,不要执行mythread.py,然后让线程检查exitFlag并从main.py改变它。

答案 1 :(得分:1)

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

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

将这两个建议纳入您的答案会导致类似这样的事情(未经测试):

main.py

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)

答案 2 :(得分:0)

这是工作解决方案;

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_class导入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)

- 或 -

thread = MyThread2(threadID, tName, workQueue)