如何确保共享变量是线程安全的?

时间:2011-12-01 11:08:30

标签: python multithreading thread-safety

我面临类似的问题:

DemoVar = 100 #### or whatever

def DemoMultiThreadMethod(mode):
    DemoRLock.acquire()

    DemoVar = 0 #### or random value
    ...
    Other resources which do not support multi-threaded access

    if mode == 0:
        do A with DemoVar

    elif mode == 1:
        do B with DemoVar
    ...

    DemoRLock.release()

...

def DecideAfterDemo(self):
    NewThread = threading.Thread(target = DemoMultiThreadMethod, args = (RandomMode, ))
    NewThread.start()

    NewThread.join()

    Result = DemoVar

    if Result == SpecificValue:
        Do something
    else:
        Do another
    ...

...

def SpawnThreads(self): 
    #### hundreds of DecideAfterDemo running
    Counter = 0

    while Counter < 1000:
        SpawnAThread = threading.Thread(target = DecideAfterDemo, args = ())
        SpawnAThread.Start()

... 

如何确保运行Result = DemoVar安全?

我的意思是,如果有大量等待处理的锁定DemoMultiThreadMethod,您实际上并不知道DemoVar = 0 #### or random valueResult = DemoVar中的哪一个会先运行它们是原子操作(如果我错了,请纠正我),这意味着如果池中有太多线程,Result = DemoVar可能不安全。我能想到的解决方案是在time.sleep(0.01)之后添加DemoRLock.acquire()以确保Result = DemoVar先运行,但这会失去一些生产力。还有更好的主意吗?

2 个答案:

答案 0 :(得分:1)

你想要的是从DemoMultiThreadMethod向DecideAfterDemo发送一些值(DemoVar)。虽然你可以使用一些消息传递库,但最简单的方法是定义线程类...像这样(未经测试):

class DemoMultiThread(threading.Thread):
     def __init__(self, mode):
         self.mode = mode
         threading.Thread.__init__(self)
     def run(run):
         mode = self.mode
         DemoRLock.acquire()
         ...
         self.result = DemoVar
         DemoRLock.release()

def DecideAfterDemo(self):
     NewThread = DemoMultiThread(mode)
     NewThread.start()
     NewThread.join()
     Result = NewThread.result
     ....

答案 1 :(得分:0)

现在每当我尝试与多个线程交换/共享信息时,我会立即转到Queue模块,这样更方便。