Является ли этот код Python потокобезопасным? - PullRequest
1 голос
/ 12 ноября 2009

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

Это мой код 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 голосов
/ 12 ноября 2009

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

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...