process to read: 16628
process to write: 16440
生产包子[0]
吃掉包子[0]
process to read: 16628
process to write: 16440
生产包子[1]
吃掉包子[1]
process to read: 16628
process to write: 16440
生产包子[2]
吃掉包子[2]
......
通过结果发现是两个进程通过队列在通信,生产一个包子,吃掉一个包子。
什么是生产者消费者模型
在python中,生产者消费者模型是一个很典型而且很经典的例子。
队列的概念就是在生产者和消费者中间加一个类似仓库的中间层,生产者不在直接对应消费者,而是生产者将生产好的东西放置到仓库中,而当消费者需要
的时候,自己去仓库中取出东西就好。这样做有以下几个优点:
1. 解耦
2. 支持并发
3. 支持忙闲不均
python多线程模型
多任务可以由多进程完成,也可以由一个进程内的多线程完成。一个进程中至少有一个线程。线程是操作系统直接支持的执行单元。
threading模块提供python对线程的使用
1. 线程的基本用法
启动一个线程就是把一个函数传入并创建Thread实例,然后调用start()开始执行,语法和进程差不多
#!_*_coding:utf-8_*_
# Author: hkey
import threading, time
def run_thread():
print('thread %s running...' % threading.current_thread().name)
n = 0
while n < 5:
n += 1
print('thread %s >>> %s' % (threading.current_thread().name, n))
time.sleep(1)
print('thread %s ended.' % threading.current_thread().name)
if __name__ == '__main__':
print('threading %s is running...' % threading.current_thread().name)
t = threading.Thread(target=run_thread,)
t.start()
t.join()
print('thread %s ended.' % threading.current_thread().name)
输出结果:
threading MainThread is running...
thread LoopThread running...
thread LoopThread >>> 1
thread LoopThread >>> 2
thread LoopThread >>> 3
thread LoopThread >>> 4
thread LoopThread >>> 5
thread LoopThread ended.
thread MainThread ended.
任何一个进程默认就有一个线程,我们把该线程称为主线程,主线程又可以启动新的线程,python的threading模块有个current_thread()函数,
它永远返回当前线程的实例。主线程的名字叫 MainThread,子线程的名字在创建时指定,我们用LoopThread命名子线程。
2. 线程的型号量
相对于进程来说,线程占用的资源就很小,因此没有使用到线程池的概念,但是要实现类似线程池的功能可以使用线程的型号量来做限制
线程的信号量是同时允许一定数量的线程更改数据,主要作用在于限制线程的并发。
#!_*_coding:utf-8_*_
#__author__:"hkey"
import threading, time, os
sem = threading.BoundedSemaphore(3) # 调用BoundedSemaphore方法限制3个线程的并发
def run():
sem.acquire() # 开始
print('threading running', threading.current_thread().name)
time.sleep(1)
sem.release() # 结束
if __name__ == '__main__':
for i in range(10):
t = threading.Thread(target=run)
t.start()
3. 线程的锁Lock
由于线程是共享进程的地址空间,所以在多线程的环境下,锁就显得尤为重要。多线程编程,在不加锁的情况下,同时对一个全局变量做修改,基本上全是错误。
#!_*_coding:utf-8_*_
#__author__:"hkey"
import threading
balance = 0
def run_thread(n):
global balance
for i in range(10000000):
balance = balance + n
balance = balance - n
if __name__ == '__main__':
t1 = threading.Thread(target=run_thread, args=(5,))
t2 = threading.Thread(target=run_thread, args=(8,))
t1.start()
t2.start()
t1.join()
t2.join()
print(balance)
输出结果:
-86
多线程编程加锁实例如下: