2009-11-12 4 views
1

Я пытаюсь сделать мой кусок кода без потоковой безопасности, чтобы играть с некоторыми исключениями, которые я хочу добавить позже.Является ли этот код на питоне потокобезопасным?

Это мой питон код:

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) и получили ответ. Почему вы задаете один и тот же вопрос с примером кода, который логически идентичен, но излишне сложнее? –

ответ

0

У вас есть операция Read-Modify-Write в основном. Если вы хотите, чтобы все было в порядке, лучше всего задержать задержку между чтением и записью.

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

Использование сна не превращает какой-либо кусок не-потокобезопасного кода в потокобезопасный, он лишь снижает вероятность одновременного доступа к критическому ресурсу. –

+0

Не могли бы вы прочитать вопрос и ответить до начала опроса ... Я никогда не говорил это сделает его потокобезопасным! И OP _ask_ не делал его потокобезопасным. Напротив, дело здесь в том, чтобы сделать _rise_ вероятность того, что он потерпит неудачу из-за его non-threadsafeness ... – 246tNt

+0

Ах, вы правы. Извините, я слишком быстро отреагировал. Я страдал от сна в приемочных тестах .... Я попытался отменить нижний план, но я не могу, если ответ не изменен. –

Смежные вопросы