在看这篇文章之前请先看
本文采取例子进行循序渐进。
多线程无锁
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| import asyncio from concurrent.futures import ThreadPoolExecutor, as_completed import time import threading import random
lock = threading.Lock()
num = 0
def add(): global num for i in range(1000000): num += 1
def sub(): global num for i in range(1000000): num -= 1
if __name__ == '__main__': sub1 = threading.Thread(target=add) sub2 = threading.Thread(target=sub)
sub1.start() sub2.start()
sub1.join() sub2.join()
print(num)
|
每次输出都不一样
多线程有锁
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| import asyncio from concurrent.futures import ThreadPoolExecutor, as_completed import time import threading import random
lock = threading.Lock()
num = 0
def add(): global num for i in range(1000000): lock.acquire() num += 1 lock.release()
def sub(): global num for i in range(1000000): lock.acquire() num -= 1 lock.release()
if __name__ == '__main__':
sub1 = threading.Thread(target=add) sub2 = threading.Thread(target=sub)
sub1.start() sub2.start()
sub1.join() sub2.join()
print(num)
|
输出 0
线程池无锁
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| import asyncio from concurrent.futures import ThreadPoolExecutor, as_completed import time import threading import random
lock = threading.Lock()
num = 0
def add(): global num for i in range(1000000): num += 1
def sub(): global num for i in range(1000000): num -= 1
if __name__ == '__main__': task_list = [] pool = ThreadPoolExecutor(max_workers=2) task = pool.submit(add) task_list.append(task) task2 = pool.submit(sub) task_list.append(task2)
print(num)
|
每次输出都不一样。
线程池有锁
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| import asyncio from concurrent.futures import ThreadPoolExecutor, as_completed import time import threading import random
lock = threading.Lock()
num = 0
def add(): global num for i in range(1000000): lock.acquire() num += 1 lock.release()
def sub(): global num for i in range(1000000): lock.acquire() num -= 1 lock.release()
if __name__ == '__main__': task_list = [] pool = ThreadPoolExecutor(max_workers=2) task = pool.submit(add) task_list.append(task) task2 = pool.submit(sub) task_list.append(task2)
print(num)
|
发现输出也不是 0
。
这是因为,多线程在运行的时候,主线程没有等待多线程运行完就直接运行了主线程,所以,我们要加一个判断,等多线程运行完了,再运行主线程。
线程池有锁 优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| import asyncio from concurrent.futures import ThreadPoolExecutor, as_completed import time import threading import random
lock = threading.Lock()
num = 0
def add(): global num for i in range(1000000): lock.acquire() num += 1 lock.release()
def sub(): global num for i in range(1000000): lock.acquire() num -= 1 lock.release()
if __name__ == '__main__': task_list = [] pool = ThreadPoolExecutor(max_workers=2) task = pool.submit(add) task_list.append(task) task2 = pool.submit(sub) task_list.append(task2)
for result in as_completed(task_list): data = result.result()
print(num)
|
输出 0
。