Python进程及线程编程(3)

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

多线程编程加锁实例如下:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/065d8208ae91fda8e3f9161255ad5f63.html