2009-11-12 7 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

기본적으로 읽기 - 수정 - 쓰기 작업이 있습니다. 일들이 엉망이 되길 원한다면, 읽기와 쓰기 사이의 지연을 도입하는 것이 가장 좋습니다.

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

downvoting을하기 전에 질문과 대답을 읽을 수 있습니까? 그것은 스레드가 안전하게 만들 것입니다! 둘 다 OP_ask_를 쓰레드 안전을 위해 만들지도 않았다. 확실히 반대쪽, 여기 요점은 그것의 non-threadsafeness 때문에 실패 할 확률을 _rise_으로 만드는 것입니다 ... – 246tNt

+0

에헴, 당신 말이 맞아요. 미안, 나는 너무 빨리 반응했다. 나는 수락 테스트에서 잠들었습니다 .... 나는 downvote를 취소하려했지만, 대답이 수정되지 않는 한 할 수 없습니다. –

관련 문제