Terry Jo
Terry Jo

Reputation: 30

I cannot understand why this thread situation doesn't work <Thread lock doesn't work>

I used the threading.Lock() not to threads access to the shared resource at the same time. But, in my code case, it doesn't work.

I know that instead of using Writer(in my code), making this class as function, then threading lock works and results 0. But I want to know why my code doesn't work. It seems as same situation for me.

import threading

global lock
lock = threading.Lock()

class Counter:
    def __init__(self):
        self.count = 0

    def increment(self, offset):
        self.count += offset


class Writer(object):
    def __init__(self, counter: Counter):
        self.counter = counter

    def write(self, value):
        with lock:
            self.counter.increment(value)

if __name__ == "__main__":
    counter = Counter()

    def run(loop, value):
        writer = Writer(counter)
        for _ in range(loop):
            writer.write(value)

    t1 = threading.Thread(target=run, args=(100000, 1))
    t2 = threading.Thread(target=run, args=(100000, -1))

    t1.start()
    t2.start()

    print(counter.count)

I expect result is 0. But Not 0.

Upvotes: 0

Views: 65

Answers (1)

Kostas Charitidis
Kostas Charitidis

Reputation: 3103

I think it's because the threads are still running. if you try to pause for a second then it prints 0. Like this:

import threading
import time
global lock
lock = threading.Lock()

class Counter:
    def __init__(self):
        self.count = 0

    def increment(self, offset):
        self.count += offset


class Writer(object):
    def __init__(self, counter: Counter):
        self.counter = counter

    def write(self, value):
        with lock:
            self.counter.increment(value)


if __name__ == "__main__":
    counter = Counter()

    def run(loop, value):
        writer = Writer(counter)
        for _ in range(loop):
            writer.write(value)

    t1 = threading.Thread(target=run, args=(100000, 1))
    t2 = threading.Thread(target=run, args=(100000, -1))

    t1.start()
    t2.start()
    time.sleep(1)
    print(counter.count)

Upvotes: 2

Related Questions