线程间的通信在多线程编程过程中难以避免,常见的线程间通信方式有两种:
- 共享变量
- 通过消息队列Queue实现
1. 共享变量
目前接触的问题来看,适应于解释多线程编程过程中一个典型实例
nums = 0
def InsertNums() :
global nums
for i in range(10000000) :
nums += 1
def DeleteNums() :
global nums
for j in range(10000000) :
nums -= 1
import threading
t1 = threading.Thread(target=InsertNums)
t2 = threading.Thread(target=DeleteNums)
t1.start()
t2.start()
t1.join()
t2.join()
上述实例中InsertNums函数以及DeleteNum函数共享了全局变量nums分别执行+操作以及-操作,但是执行后得到的结果并非预期的nums = 0
所以这个代码实例很好的暴露出了多线程线程间通信存在的问题即线程不安全目前解决线程不安全的方法就是加锁
import threading
locker = threading.Lock()
nums = 0
def InsertNums() :
global nums
global locker
for i in range(10000000) :
locker.acquire()
nums += 1
locker.release()
def DeleteNums() :
global nums
global locker
for j in range(10000000) :
locker.acquire()
nums -= 1
locker.release()
2. 消息队列
Queue中提供了线程之间的通讯机制,能够保证线程的安全
from time import sleep
import threading
from Queue import Queue
def writeQ(queue):
for i in range(100):
tmp = queue.get(True)
queue.put(tmp + 1, True)
def readQ(queue):
for i in range(100):
tmp = queue.get(True)
queue.put(tmp + 1, True)
def main():
q = Queue(32)
q.put(0, True)
threading.Thread(target=writeQ, args = (q,)).start()
threading.Thread(target=readQ, args = (q,)).start()
sleep(2)
print q.get(True)
if __name__ == '__main__':
main()