day35

joinablequeue

from multiprocessing import JoinableQueue
q = JoinableQueue()
# q.get()
q.put('123')
q.put('678')
q.task_done()#用来发送一个任务完成的信号
q.task_done()
print('...........')
q.join()#等待队列中的数据被处理完毕
print('over')

'''
注:jion会等待队列中所有的数据处理完毕,一个put需要对应一个task_done,当队列取空时调用task_done会出现     valueerro异常.
  虽然task_done用来发送一个任务完成得信号,但是队列并不会关心你有没有取出数据,就是调用get函数
'''

生产者消费者模型中使用joinblequeue

import random
import time
from multiprocessing import Process, Queue,JoinableQueue


def make_hotdog(name,q):
   for i in range(5):
       time.sleep(random.randint(1,3))
       print("%s生产了热狗%s" % (name,i))
       q.put("%s的%s号热狗" % (name,i))
   # q.put(None)

def eat_hotdog(name,q):
   while True:
       hotdog = q.get()
       # if not hotdog:
       #     break
       time.sleep(random.randint(1, 3))
       print("%s吃掉了%s" % (name,hotdog))
       # 必须记录 该数据 处理完成了
       q.task_done()

if __name__ == '__main__':
   q = JoinableQueue()

   p = Process(target=make_hotdog,args=("owen的热狗店",q))
   p2 = Process(target=make_hotdog,args=("bgon的热狗店",q))
   p3 = Process(target=make_hotdog,args=("jerry的热狗店",q))

   c = Process(target=eat_hotdog,args=("思聪",q))
   c.daemon = True
   c2 = Process(target=eat_hotdog, args=("大葱", q))
   c2.daemon = True
   # c3 = Process(target=eat_hotdog, args=("二葱", q))

   p.start()
   p2.start()
   p3.start()

   c.start()
   c2.start()
   # c3.start()

   # 目前的思路 是当商家做完以后 放一个None 作为结束标志   不够好 必须明确商家和消费者的个数


   # 明确商家生成完毕 在明确消费者吃完了 就算结束
   p.join()
   print("第一家生成完毕")

   p2.join()
   print("第二家生成完毕")

   p3.join()
   print("第三家生成完毕")


   # 消费者吃完了
   q.join()
   print("消费吃完了!")
   print("美好的一天结束了!")

线程

# 线程 线程是操作系统最小的运算调度单位,线程别包含在进程中
# 进程根本不能被执行,它是一个资源单位,其包含了运行程序的所有资源,线程才是执行单位
# 没有线程,进程中的资源无法被利用起来.所以一个进程至少包含一个线程,称之为主线程
# 当我们启动一个程序时,操作系统就会自己为这个程序创建一个主线程
# 线程可以由程序后期开启,自己开启线程称之为子线程.但是不要误会,线程之间并没有父子关系
# 开启多个线程主要为了提高效率
#同一个进程中的线程数据时共享的
#创建线程比创建进程的开销小
from threading import Thread
def task():
   print(1 + 1)
   print('子线程running')


t = Thread(target=task)
#守护线程
t.deamon = True
t.start()
print('主线程over')


class MyThread(Thread):
def run(self):
       print('子线程')
MyThread().start()

#守护线程得概念和守护进程一样,值得注意,守护线程在自己得代码执行完毕以后就死亡了,只有在代码没有执行完,主程死亡了,守护进程才会跟着一起死亡,主进程需要等待非守护进程结束才能结束

多线程

#线程间数据共享实例
from threading import Thread
a = 10
def task():
   global a
   print('子线程........')
   a = 20


t = Thread(target=task)
t.start()
t.join()#主线程等待子线程执行完毕
print(a)
#不能像进程一样将a作为参数传过去,因为我们用类和函数来表示线程和线程要执行得代码,所以传过去在python语法中就时两个变量了

线程的安全问题

#锁
from threading import Thread,enumerate,Lock
import time

number = 10

lock = Lock()

def task():
   global number
   lock.acquire()
   a = number
   time.sleep(0.1)
   number = a - 1
   lock.release()

for i in range(10):
   t = Thread(target=task)
   t.start()

for t in enumerate()[1:]:
   # print(t)
   t.join()

print(number)

# 用于访问当前正在运行的所有线程
# print(enumerate())

#死锁
'''当程序出现了不止一把锁,分别被不同的线程持有, 有一个资源要想使用必须同时具备两把锁
  这时候程序就会进程无限卡死状态 ,这就称之为死锁
'''
import time
# 盘子
lock1 = Lock()

# 筷子
lock2 = Lock()

def eat1():
   lock1.acquire()
   print("%s抢到了盘子" % current_thread().name)
   time.sleep(0.5)
   lock2.acquire()
   print("%s抢到了筷子" % current_thread().name)

   print("%s开吃了!" % current_thread().name)
   lock2.release()
   print("%s放下筷子" % current_thread().name)

   lock1.release()
   print("%s放下盘子" % current_thread().name)


def eat2():
   lock2.acquire()
   print("%s抢到了筷子" % current_thread().name)

   lock1.acquire()
   print("%s抢到了盘子" % current_thread().name)


   print("%s开吃了!" % current_thread().name)


   lock1.release()
   print("%s放下盘子" % current_thread().name)
   lock2.release()
   print("%s放下筷子" % current_thread().name)


t1 = Thread(target=eat1)


t2 = Thread(target=eat2)

t1.start()
t2.start()

RLOCK和信号量

'''
Rlock 称之为递归锁或者可重入锁

Rlock不是用来解决死锁问题的

与Lock唯一的区别:
Rlock同一线程可以多次执行acquire 但是执行几次acquire就应该对应release几次
   
如果一个线程已经执行过acquire 其他线程将无法执行acquire
'''

"""
信号量 了解
Semaphore

用途: 仅用于控制并发访问   并不能防止并发修改造成的问题
"""

from threading import Semaphore, Thread
import time

s = Semaphore(5)#参数用于表示可以由多少并发访问
def task():
   s.acquire()
   print("子run")
   time.sleep(3)
   print("子over")
   s.release()

for i in range(10):
   t = Thread(target=task)
   t.start()
posted @ 2019-06-04 22:14  月薪20k  阅读(96)  评论(0)    收藏  举报