并发编程之生产者消费者模型以及线程等相关内容-38

1.生产者消费者模型

# 初级生产者消费者模型
# import time
# import random
# from multiprocessing import Process, Queue
#
#
# def producer(name, food, q):
#     for i in range(10):
#         data = '%s 制造了%s' % (name, food)
#         # 模拟制造食物延迟
#         time.sleep(random.randint(1, 3))
#         print(data)
#         q.put(food)
#
#
# def consumer(name, q):
#     while True:
#         food = q.get()
#         # 模拟吃食物延迟
#         time.sleep(random.randint(1, 3))
#         print('%s消费了%s' % (name, food))
#
#
# if __name__ == '__main__':
#     q = Queue()
#     # 创造一个生产者
#     p = Process(target=producer, args=('egon', '包子', q))
#     p.start()
#
#     # 创造一个消费者
#     c = Process(target=consumer, args=('鸡哥', q))
#     c.start()


# 如果queue中没有数据了,消费者会一直卡住
# import time
# import random
# from multiprocessing import Process, Queue
#
# def producer(name, food, q):
#     for i in range(10):
#         data = '%s 制造了%s' % (name, food)
#         # 模拟制造食物延迟
#         time.sleep(random.randint(1, 3))
#         print(data)
#         q.put(food)
#     q.put(None)
#
#
# def consumer(name, q):
#     while True:
#         food = q.get()
#         if food is None:return # 当队列中取出None,之间结束
#         # 模拟吃食物延迟
#         time.sleep(random.randint(1, 3))
#         print('%s消费了%s' % (name, food))
#
#
# if __name__ == '__main__':
#     q = Queue()
#     # 创造一个生产者
#     p = Process(target=producer, args=('egon', '包子', q))
#     p.start()
#
#     # 创造一个消费者
#     c = Process(target=consumer, args=('鸡哥', q))
#     c.start()


# # 制造两个消费者
# import time
# import random
# from multiprocessing import Process, Queue
#
# def producer(name, food, q):
#     for i in range(10):
#         data = '%s 制造了%s' % (name, food)
#         # 模拟制造食物延迟
#         time.sleep(random.randint(1, 3))
#         print(data)
#         q.put(food)
#
#
# def consumer(name, q):
#     while True:
#         food = q.get()
#         if food is None:return # 当队列中取出None,之间结束
#         # 模拟吃食物延迟
#         time.sleep(random.randint(1, 3))
#         print('%s消费了%s' % (name, food))
#
#
# if __name__ == '__main__':
#     q = Queue()
#     # 创造一个生产者
#     p = Process(target=producer, args=('egon', '包子', q))
#     p.start()
#
#     # 创造一个消费者
#     c = Process(target=consumer, args=('鸡哥', q))
#     c.start()
#     c1 = Process(target=consumer, args=('王铁蛋', q))
#     c1.start()
#     # 生产者生产完毕,放两个None
#     p.join() # 等待p进程执行完成再放
#     q.put(None)
#     q.put(None)


# 多个生产者和多个消费者
# 制造两个消费者
# import time
# import random
# from multiprocessing import Process, Queue
#
# def producer(name, food, q):
#     for i in range(10):
#         data = '%s 制造了%s' % (name, food)
#         # 模拟制造食物延迟
#         time.sleep(random.randint(1, 3))
#         print(data)
#         q.put(food)
#
#
# def consumer(name, q):
#     while True:
#         food = q.get()
#         if food is None:return # 当队列中取出None,之间结束
#         # 模拟吃食物延迟
#         time.sleep(random.randint(1, 3))
#         print('%s消费了%s' % (name, food))
#
#
# if __name__ == '__main__':
#     q = Queue()
#     # 创造一个生产者
#     p = Process(target=producer, args=('egon', '包子', q))
#     p.start()
#
#     p1 = Process(target=producer, args=('alex', '泔水', q))
#     p1.start()
#     # 创造一个消费者
#     c = Process(target=consumer, args=('鸡哥', q))
#     c.start()
#     c1 = Process(target=consumer, args=('王铁蛋', q))
#     c1.start()
#     c2 = Process(target=consumer, args=('李铁柱', q))
#     c2.start()
#     # 生产者生产完毕,放两个None
#     p.join() # 等待p进程执行完成再放
#     p1.join() # 等待p1(另一个生产者)进程执行完成再放
#
#     q.put(None)
#     q.put(None)
#     q.put(None)


# 最终版本,不用放None
import time
import random
from multiprocessing import Process, Queue, JoinableQueue


def producer(name, food, q):
   for i in range(10):
       data = '%s 制造了%s' % (name, food)
       # 模拟制造食物延迟
       time.sleep(random.randint(1, 3))
       print(data)
       q.put(food)


def consumer(name, q):
   while True:
       food = q.get()
       # 模拟吃食物延迟
       time.sleep(random.randint(1, 3))
       print('%s消费了%s' % (name, food))
       q.task_done()  # 把队列中维护的数字减一


if __name__ == '__main__':
   # q = Queue()
   # 内部为何了一个数字,放一个数字会加一
   # 消费一个数字减一
   q = JoinableQueue()
   # 创造一个生产者
   p = Process(target=producer, args=('egon', '包子', q))
   p.start()

   p1 = Process(target=producer, args=('alex', '泔水', q))
   p1.start()

   # 创造一个消费者
   c = Process(target=consumer, args=('鸡哥', q))
   c.daemon = True
   c.start()

   c1 = Process(target=consumer, args=('王铁蛋', q))
   c1.daemon = True
   c1.start()
   c2 = Process(target=consumer, args=('李铁柱', q))
   c2.daemon = True
   c2.start()
   # 主结束,消费进程也结束,把每个消费进程都设置成守护进程

   # 等待所有生产者生产结束,主进程再结束
   p.join()
   p1.join()
   q.join()  # 会卡再者,一直等待q队列中数据没有了,才继续往下走
   print('生产者结束了,主进程结束')

# JoinableQueue()
# 每放一个值,数字加一
# 取值不会减一,q.task_done()
# q.join() 一直阻塞,当q没有值了,才继续走

2.开启线程的两种方式

第一种
from threading import Thread
import time

def task():
   print('开始')
   time.sleep(1)
   print('结束')


if __name__ == '__main__':
   t=Thread(target=task,) # 实例化得到一个对象
   t.start() # 对象.start()启动线程
   print('主')

第二种,通过类继承的方式
from threading import Thread
import time

class MyThread(Thread):
   def run(self):
       print('开始')
       time.sleep(1)
       print('结束')

if __name__ == '__main__':
   t=MyThread()
   t.start()
   print('主')

3.join的使用

from threading import Thread

import time


def task(n):
   print('开始')
   time.sleep(n)
   print('结束')


if __name__ == '__main__':
   t = Thread(target=task, args=(2,))
   t.start()

   t1 = Thread(target=task, args=(3,))
   t1.start()

   t.join()  # 等待子进程执行结束
   t1.join()
   print('主')

4.多线程下的数据共享

from threading import Thread

import time

money = 99


def task(n):
   global money
   money = n
   print('开始')
   # time.sleep(n)
   print('结束')


if __name__ == '__main__':
   t = Thread(target=task, args=(2,))
   t.start()

   t1 = Thread(target=task, args=(66,))
   t1.start()

   t.join()
   t1.join()
   print(money)
   print('主')

5.线程对象的其他方法

# from threading import Thread, current_thread,active_count
# import time
#
#
# def task():
#     print('开始')
#     print(current_thread().name)   # 线程名字
#     time.sleep(1)
#     print('结束')
#
#
#
# if __name__ == '__main__':
#     t1 = Thread(target=task,name='egon')
#     t2 = Thread(target=task)
#     t1.start()
#     t2.start()
#     print(active_count()) # 打印出3 ,开了两个线程,还有一个主线程


from threading import Thread, current_thread, active_count
import time
import os


def task(n):
   print('开始')
   print(current_thread().name)  # 线程名字
   # 如果打印进程id号,会是什么
   print(os.getpid())
   time.sleep(n)
   print('结束')


if __name__ == '__main__':
   t1 = Thread(target=task, name='egon', args=(2,))
   t2 = Thread(target=task, args=(8,))
   t1.start()
   t2.start()
   t1.join()
   print('---------', t1.is_alive())
   print('---------', t2.is_alive())

   # 当作线程id号
   print('*********', t1.ident)
   print('*********', t2.ident)

   print(os.getpid())
   print(active_count())  # 打印出3 ,开了两个线程,还有一个主线程

# 必须知道的
'''
1 线程t.name t.getName()
2 当前进程下有几个线程存活active_count
3 t1.is_alive() 当前线程是否存活
4 t1.ident 当作是线程id号

'''

6.守护线程

from threading import Thread, current_thread, active_count
import time
import os


def task(n):
   print('开始')
   time.sleep(n)
   # print('-----',active_count())
   print('结束')


if __name__ == '__main__':
   t1 = Thread(target=task, name='egon', args=(10,))
   # t1.daemon = True
   t1.setDaemon(True)
   t1.start()

   t2 = Thread(target=task, name='egon', args=(4,))
   t2.start()

   print('主')

7.锁

from threading import Thread, Lock
# from multiprocessing import Lock
import time
import random

money = 99


def task(n, mutex):
   global money
   # 在修改数据的时候,枷锁
   mutex.acquire()
   temp = money
   time.sleep(0.1)

   money = temp - 1
   # 修改完以后,释放锁,其它线程就能再次抢到锁
   mutex.release()


if __name__ == '__main__':
   ll = []
   mutex = Lock()
   for i in range(10):
       t = Thread(target=task, args=(i, mutex))
       t.start()
       ll.append(t)

   for i in ll:
       i.join()

   print(money)

 

原文地址:https://www.cnblogs.com/usherwang/p/13561966.html