共享资源时如何避免python线程中的全局?

时间:2012-12-04 09:41:37

标签: python multithreading global

我正在尝试在python中构建一个依赖于多个线程的程序,并在线程之间共享数据。我试图避免使用全局关键字,但到目前为止无法实现。

作为一个简单的例子(下面的代码),我的main()函数产生一个线程thread1,它应该能够访问变量count,在这种情况下只是为了打印它。同时,main()迭代这个变量,而thread1应该能够看到计数的变化。这里有一些自包含的代码:

import threading
import time

class myThread (threading.Thread):

    def __init__(self, threadID):
        self.threadID = threadID
        threading.Thread.__init__(self)

    def run(self):
        global count
        for i in range(10):
            print "count is now: ", count, " for thread ", self.threadID, "\n"
            time.sleep(5)


def main():

    global count
    count = 0

    # spawn one or more threads
    thread1 = myThread(1)
    thread1.start()

    for i in range(20):
        time.sleep(2)
        count = count + 1

    # wait for thread1 to finish
    thread1.join()

main()

在python中读取线程时,我没有找到任何其他方法来做到这一点,而不是使用全局。但是,在阅读有关全球的内容时,大多数人都说你应该很少使用它,这是有充分理由的,有些人甚至认为它应该完全从python中删除。所以我想知道是否有一种替代方法让thread1“被动地”检测到main()具有迭代计数,并访问该新值?例如。我不太了解python和指针(它们甚至存在于python中吗?),但我无论如何都认为这正是全球所达到的。

理想情况下,我可以从main()调用一个thread1方法,只要迭代count就设置一个新的self.count,但是由于thread1有一个阻塞的run()方法,我看不懂怎么做没有在thread1中有另一个独立的线程,这看起来太复杂了。

1 个答案:

答案 0 :(得分:2)

您可以创建线程对象并填充类属性。

import threading
class MyThreadClass(threading.Thread):
  def __init__(self, fruits):
    threading.Thread.__init__(self)
    self.fruits = fruits    

  def run(self):
    self.fruits.append('banana')  

list_fruit = ['apple', 'orange']    
print 'BEFORE:', list_fruit
thread = MyThreadClass(list_fruit)
thread.start() 
thread.join() #Wait for the thread to finish
print 'AFTER:', list_fruit

输出:

BEFORE: ['apple', 'orange']
AFTER: ['apple', 'orange', 'banana']

对于您的情况,您可以尝试:

import threading
import time

class myThread (threading.Thread):

    def __init__(self, threadID):
        self.threadID = threadID
        self.count = 0
        threading.Thread.__init__(self)

    def run(self):
        for i in range(10):
            print "count is now: ", self.count, " for thread ", self.threadID, "\n"
            time.sleep(5)


def main():    
    # spawn one or more threads
    thread1 = myThread(1)
    thread1.start()

    for i in range(20):
        time.sleep(2)
        thread1.count = thread1.count + 1

    # wait for thread1 to finish
    thread1.join()
    print thread1.count

main()

如果要使用多个线程之间共享的相同计数,可以将计数放在仅包含一个元素的列表中。 这样,在为线程属性分配计数时,它不会是硬拷贝。