2009-11-12 94 views
1

我试图让我的代码块非线程安全,以便玩弄一些我希望稍后添加的异常。这个python代码是线程安全的吗?

这是我的Python代码:

from time import sleep 
from decimal import * 
from threading import Lock 
import random 

def inc_gen(c): 
    """ 
    Increment generator 
    """ 
    while True: 
     #getting sleep period 
     timing_rand = random.randrange(0,1000) 
     print "INC: Sleeping for " + str(Decimal(timing_rand)/Decimal(1000)) 
     sleep(Decimal(timing_rand)/Decimal(1000)) 
     c.inc() 
     yield c 

def dec_gen(c): 
    """ 
    decrement generator 
    """ 
    while True: 
     #getting sleep period 
     timing_rand = random.randrange(0,1000) 
     print "DEC: Sleeping for " + str(Decimal(timing_rand)/Decimal(1000)) 
     sleep(Decimal(timing_rand)/Decimal(1000)) 
     c.dec() 
     yield c 

class something(): 
    """ 
    We use an obj instead of an atomic variable c, we can have "threads" 
    simulating shared resources, instead of a single variable, to avoid 
    atomic instructions. (which is thread-safe in python thanks to GIL) 
    """ 
    def __init__(self): 
     self.c = 0 
    def inc(self): 
     self.c += 1 
    def dec(self): 
     self.c -= 1 
    def value(self): 
     return self.c 

def main(): 
    """ 
    main() function 
    """ 
    obj = something() 
    counters = [inc_gen(obj),dec_gen(obj)] 

    #we only want inc_gen 10 times, and dec_gen 10 times. 
    inc = 0 #number of times inc_gen is added 
    dec = 0 #number of times dec_gen is added 

    while True: 
     #choosing the next counter 
     if inc < 10 and dec < 10: 
      counter_rand = random.randrange(0,2) 
      if counter_rand == 0: 
       inc += 1 
      else: dec += 1 
     elif inc < 10 and dec == 10: 
      inc += 1 
      counter_rand = 0 
     elif dec < 10 and inc == 10: 
      dec += 1 
      counter_rand = 1 
     else: break 

     counters[counter_rand].next() 

    #print for testing 
    print "Final value of c: " + str(obj.value()) 

if __name__ == "__main__": 
    main() 

有代码可能导致其不为0

它是线程安全的最终值我希望它做的是什么?如果不是,我该如何使它不是线程安全的?

+2

呃,你刚才问过这个(http://stackoverflow.com/questions/1717393),并且得到了答案。你为什么用示例代码问完全相同的问题,这些代码在逻辑上相同但不必要更复杂? – 2009-11-12 09:13:10

回答

0

基本上,您有读取 - 修改 - 写入操作。如果你想确保事情变得不合时宜,最好的办法就是延迟阅读和写作之间的延迟。

def inc(self): 
    v = self.c 
    time.sleep(random.random()) # Should probably limit it to a few hundred ms 
    self.c = v + 1 

def dec(self): 
    v = self.c 
    time.sleep(random.random()) # Should probably limit it to a few hundred ms 
    self.c = v - 1 
+0

使用睡眠不会将任何非线程安全代码转换为线程安全代码,它只会降低同时访问关键资源的可能性 – 2016-05-10 09:08:30

+0

您可以在downvoting之前阅读问题和答案......我从未说过它会使它线程安全! OP也没有让线程安全。恰恰相反,这里的重点在于使它失败的可能性在于它的非线程安全性...... – 246tNt 2016-05-27 13:15:17

+0

ahem,你是对的。对不起,我反应太快了。我在验收测试中遭受了沉重的打击......我试图取消downvote,但除非答案被修改,否则我不能。 – 2016-05-30 07:42:55