这个python代码是线程安全的吗?

时间:2009-11-12 09:04:10

标签: 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.

它是线程安全的吗?如果没有,我怎么能使它不是线程安全的?

1 个答案:

答案 0 :(得分: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