在多线程编程中常用到的一个概念就是锁,它用于将线程需要独占的资源进行加锁,使用后再进行释放,防止死锁发生。
此处给出一个不加锁的多线程例子(实现整数n在每个线程内加1并打印):
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import threading
import time
class myThread(threading.Thread):
def __init__(self, TID, times):
super(myThread, self).__init__()
self.TID = TID
self.times = times
def run(self):
fun_threading(self.TID, self.times)
def fun_threading(TID, times):
global n
time.sleep(1)
n = n + 1
print('Thread-{tid}:'.format(tid = TID), n)
n = 0
def main():
threads = []
num_threads = 6 # 线程数
ID = 1
for i in range(1, num_threads + 1):
new_thread = myThread(ID, 4) # 创建线程并加入线程队列
threads.append(new_thread)
ID += 1
for i in range(1, num_threads + 1):
threads[i - 1].start() # 启动线程活动
for i in range(1, num_threads + 1):
threads[i - 1].join()
print("Exiting Main Thread")
if __name__ == "__main__":
main()
运行结果:
Thread-2: 1
Thread-6: 4
Thread-1: 2
Thread-5: 3
Thread-4: 5
Thread-3: 6
Exiting Main Thread
会发现线程顺序是错乱的,且n的累加顺序也有问题,在某些线程内n加完1后还没来得及打印,该线程就被“抢占”了。我们加上锁之后看一下效果:
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import threading
import time
class myThread(threading.Thread):
def __init__(self, TID, times):
super(myThread, self).__init__()
self.TID = TID
self.times = times
def run(self):
if lock.acquire():
fun_threading(self.TID, self.times)
lock.release()
def fun_threading(TID, times):
global n
time.sleep(1)
n = n + 1
print('Thread-{tid}:'.format(tid = TID), n)
lock = threading.Lock()
n = 0
def main():
threads = []
num_threads = 6 # 线程数
ID = 1
for i in range(1, num_threads + 1):
new_thread = myThread(ID, 4) # 创建线程并加入线程队列
threads.append(new_thread)
ID += 1
for i in range(1, num_threads + 1):
threads[i - 1].start() # 启动线程活动
for i in range(1, num_threads + 1):
threads[i - 1].join()
print("Exiting Main Thread")
if __name__ == "__main__":
main()
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import threading
import time
class myThread(threading.Thread):
def __init__(self, TID, times):
super(myThread, self).__init__()
self.TID = TID
self.times = times
def run(self):
if lock.acquire():
fun_threading(self.TID, self.times)
lock.release()
def fun_threading(TID, times):
for i in range(1, times + 1):
print('Thread-{tid}: {Time}'.format(tid = TID, Time = time.ctime(time.time())))
time.sleep(1)
threads = []
num_threads = 3 # 线程数
ID = 1
lock = threading.Lock() # 创建锁
for i in range(1, num_threads + 1):
new_thread = myThread(ID, 4) # 创建线程并加入线程队列
threads.append(new_thread)
ID += 1
for i in range(1, num_threads + 1):
threads[i-1].start() # 启动线程活动
for i in range(1, num_threads + 1):
threads[i-1].join()
print("Exiting Main Thread")
运行结果:
Thread-1: 1
Thread-2: 2
Thread-3: 3
Thread-4: 4
Thread-5: 5
Thread-6: 6
Exiting Main Thread
发现6个线程依次打印完后将I/O交给下一个线程打印,搞定~