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

1 投票
1 回答
626 浏览
提问于 2025-04-15 15:56

我正在尝试让我的这段代码变得不安全,以便后面可以添加一些我想要的异常处理。

这是我的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

你基本上在进行一个读-修改-写的操作。如果你想确保事情变得混乱,最好的办法是在读取和写入之间引入一些延迟。

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

撰写回答