多线程是为了同步完成多项任务,通过提高资源使用效率来提高系统的效率。线程是在同一时间需要完成多项任务的时候实现的。
threading模块是python中专门提供用来做多线程编程的模块,常用类是Thread。
import threading
import time
def coding():
for x in renge(3):
print('正在写代码%s'%x)
time.sleep(1)
def drawing():
for x in renge(3):
print('正在画图%s'%x)
time.sleep(1)
def main():
t1 = threading.Thread(target=coding)
t2 = threading.Thread(target=drawing)
if __name__ == '__main__':
main()
是用threading.enumerate()函数可以看到当前线程的数量
使用threading.current_thread()可以看到当前线程信息
为了让线程代码更好的封装,可以使用threading模块下的Thread类,继承自这个类,然后实现run()方法,线程就会自动运行run()方法
import threading
import time
class CodingThread(threading.Thread):
def run(self):
def coding():
for x in renge(3):
print('正在写代码%s'%x)
time.sleep(1)
class DrawThread(threading.Thread):
def run(self):
def drawing():
for x in renge(3):
print('正在画图%s'%x)
time.sleep(1)
def multy_thread():
t1 = CodingThread()
t2 = DrawThread()
t1.start()
t2.start()
if __name__ == '__main__':
multy_thread()
多线程都是在同一个进程中运行的,因此在进程中的全局变量所有的线程都是可共享的。这就照成了一个问题,因为线程执行的顺序是无序的,有可能会造成数据错误。为了解决以上问题,threading提供了一个Lock类,这个类可以在某个线程访问某一个变量的时候加锁,其他线程此时就进不来,知道当前线程处完后,把锁释放了,其他线程次能进来处理。
import threading
VALUE = 0
gLock = threading.Lock()
def add_value():
global VALUE
gLock.acquire()
for x in range(1000000)
VALUE +=1
gLock.release()
print('value:%d' %VALUE)
def main():
for x in range(2):
t = threading.Thread(target=add_value)
t.start()
if __name__ == '__main__':
main()
生产者和消费者模式是多线程开发中经常见到的一种模式。生产者的线程专门用来生产一些数据,然后存放到一个中间的变量中。消费者再从这个中间的变量中取出数据进行消费。但是因为要使用中间变量,中间变量经常是一些全局变量,因此需要使用锁来保证数据完整性。
import threading
import random
import time
gMoney = 1000
gLock = threading.Lock()
gTotalTimes = 10
gTime = 0
class Product(threading.Thread):
def run(self):
global gMoney
global gTime
while True:
money = random.randint(100, 1000)
gLock.acquire()
if gTime >= 10:
gLock.release()
break
gMoney += money
print('%s生产了%d元钱,共计%d元钱' % (threading.current_thread(), money, gMoney))
gTime += 1
gLock.release()
time.sleep(1)
class Consumer(threading.Thread):
def run(self):
global gMoney
while True:
money = random.randint(100, 1000)
gLock.acquire()
if gMoney > money:
gMoney -= money
print('%s消费了%d元钱,余额%d元钱' % (threading.current_thread(), money, gMoney))
else:
if gTime >= gTotalTimes:
gLock.release()
break
print('%s准备消费%d元钱,剩余%d元钱,余额不足' % (threading.current_thread(), money, gMoney))
gLock.release()
time.sleep(1)
def main():
for x in range(5):
t = Product(name='生产者线程%d' % x)
t.start()
for x in range(3):
t = Consumer(name='消费者线程%d' % x)
t.start()
if __name__ == '__main__':
main()
在线程中,访问一些全局变量,加锁是一个经常的过程。如果你是想把一些数据存储到某个队列中,那么 Python内置了一个线程安全的模块叫做 queue 模块。 Python中的queue模块中提供了同步的、线程安全以列类,包括FIFO(先进出)队列 Queue,LIFO(后入先出)队列 LifoQueue。这些队列都实现了锁原语(可以理解为原子操作,即么不做,更么都做完),能够在多程中直接使
用。可以使用队列来实现线程间的同步。相关的的数如下:
1.初始化 Queue( maxsize) 创建一个先进先出的队列。
2. gsize():返回队列的大小。
3. empty():判断队列是否为空。
4.full():判断队列是否满了。
5.get():从队列中取最后一个数据
6.put():将一个数据放到队列中。