49 lines
1.2 KiB
Plaintext
49 lines
1.2 KiB
Plaintext
'''
|
|
Demonstrates the classic threading problem of multiple threads
|
|
non-atomically modifying a value concurrently by get/add/set.
|
|
|
|
Can take two arguments:
|
|
|
|
--locked Wrap access in a lock.
|
|
--threads N Create N threads.
|
|
|
|
'''
|
|
import os
|
|
if 'KUROKO_TEST_ENV' in os.environ:
|
|
return 0
|
|
|
|
import kuroko
|
|
from threading import Thread, Lock
|
|
|
|
def __main__():
|
|
|
|
# Simple flag argument processing.
|
|
let locked = '--locked' in kuroko.argv
|
|
let threadcount = 10 if '--threads' not in kuroko.argv else (int(kuroko.argv[kuroko.argv.index('--threads')+1]))
|
|
|
|
# This also demonstrates threads accessing an upvalue
|
|
# which has not yet been closed in another thread.
|
|
let i = 0
|
|
let lock = Lock()
|
|
|
|
class Incrementer(Thread):
|
|
def run():
|
|
for c in range(1000):
|
|
if locked:
|
|
with lock:
|
|
i += 1
|
|
else:
|
|
i += 1
|
|
|
|
let threads = [Incrementer() for j in range(threadcount)]
|
|
for thread in threads: thread.start()
|
|
for thread in threads: thread.join()
|
|
|
|
# Should be 1000 * threadcount - but is it? Almost definitely not without a lock!
|
|
print(i)
|
|
|
|
return 0
|
|
|
|
if __name__ == '__main__':
|
|
return __main__()
|