python3,线程,锁,队列相关实操备忘

#!/usr/bin/env python3
'''
threadin模块多线程锁的种类(通常用递归锁RLock替代普通锁Lock使用):
1.t=threading.Lock(): 单纯的锁,不过多个锁时,可能会造成死锁!
  t.acquire() 启动锁:以下代码单线程一直执行,中间不切换到其它线程
  t.release() 释放锁:让其它线程可操作
2.t.threading.RLock():
  递归锁(解决死锁问题):一个锁可重复使用,互相嵌套,内附有锁的计数器。释放锁也是由内到外,只有最外层的锁释放后,其它线程才可使用。
  释放一个锁,计数器减1
3. 信号量:也是锁的一种!以下设置可同时并发5个线程对锁内指令进行操作!某个线程先执行完,其它线程可再次进入执行!同样内含计数器
  semaphore = threading.BoundedSemaphore(5)
4.条件变量同步:也是一种锁,可实现线程之前的沟通!..默认使用递归锁RLock.
  lock_con = threading.Condition()
  lock_con.acquire()--启动锁;lock_con.release()--释放锁;lock_con.wait()--释放锁并进入阻塞状况,等待notify激活后重新从acquire开始执行;
  lock_con.notify()--通知在wait()状态的锁可以开始执行了。即激活作用!
5. 同步条件event:没有锁的功能,内含一标志位(True、False).实现不同线程之前的通讯控制
  event.isSet():返回event的状态值;
  event.set():设置event状态值为True!所有阻塞池的线程激活进入就绪状态;等待os调度;
  event.wait():如果 event.isSet() == False,将阻塞线程
  event.clear():恢复event的状态值为False
6.queue:队列,一个结构数据类型,多线程利器!默认FIFO(先进行出);自带锁!保证多线程操作时,队列里的唯一性及数据安全!
  import queue
  q = queue.Queue(10); 创建队列对象;参数10代表队列允许的数量为10个。0或是负数代表无穷大
  q.put(item,block,timeout),把item数据放入队列中,block默认True,作用是队列满时,阻塞(不报错)!,如果设置为False,则队列满时,再放数据会报错;
  timeout:设置阻塞超时;
  q.get(block,timeout):默认先进先出原则取出数据
  q.full()和q.empty():判断队列满或空。返回True或False
  q.qsize():返回队列大小

'''
import threading
import time
from random import randint
import queue


class Producer(threading.Thread):
  def run(self):
    while True:
      val = randint(0,100)
      q.put(val)
      print("面包师%s生产了%s号包子"%(self.name, str(val)))
      time.sleep(2)


class Consumer(threading.Thread):
  def run(self):
    while True:
      re = q.get()
      print("客户%s吃掉了%s号包子"%(self.name,re))
      time.sleep(0.5)

if __name__ == "__main__":
  q = queue.Queue(10) #创建一个队列,队列允许的最大成员数是10个,多了造成阻塞,得有出去的,才能进来!
  threads = [] # 放所有线程名称的列表
  for t in range(5):
    threads.append(Producer()) # 创建3个线程,对应3个生产者对象---Producer()通过类方式创建了一个线程
  threads.append(Consumer())
  for i in threads:
    i.start()
  for j in threads:
    j.join()

'''
class boss(threading.Thread):
  def run(self):
    print("%s说今天晚上大家都加班到晚上24:00"%(self.name))
    event.isSet() or event.set() # 在x or y的值只可能是x或y。 当x为true时是x, x为false时是y.即event状态只能是True
    time.sleep(5)
    print("%s:时间到了,大家可以下班了!!"%(self.name))
    event.isSet() or event.set()

class worker(threading.Thread):
  def run(self):
    event.wait() # 阻塞线程
    print("worker: ai......命苦啊。。。")
    time.sleep(1)
    event.clear()
    event.wait()
    print("worker: HAHAAHAHA")


if __name__ == "__main__":
  event = threading.Event() # 启动线程控制状态
  threads = []
  for t in range(5):
    threads.append(worker())
  threads.append(boss())
  for i in threads:
    i.start()
  for j in threads:
    j.join()
'''

'''
class Account:
  def __init__(self,id,balance):
    self.id = id
    self.balance = balance

  def withdraw(self,num):
    r.acquire()
    self.balance -= num
    r.release()

  def deposit(self,num):
    r.acquire()
    self.balance += num
    r.release()


def transfer(_from,_to,count):
  _from.withdraw(count)
  _to.deposit(count)

if __name__ == "__main__":
  r = threading.RLock() # 递归锁(解决死锁问题):一个锁可重复使用,互相嵌套,内附有锁的计数器。
  a1 = Account("zuly",1000)
  a2 = Account("mary",2000)
  t1 = threading.Thread(target = transfer, args = (a1,a2,300))
  t2 = threading.Thread(target = transfer, args = (a2,a1,100))
  t1.start()
  t2.start()
  print("%s 的 balance 是%s"%(a1.id,a1.balance))
  print("%s 的 balance 是%s"%(a2.id,a2.balance))
'''


'''
#********信号量使用************
class MyThread(threading.Thread):
  def run(self):
    semaphore.acquire()
    print("这是%s在执行代码"%(self.name))
    time.sleep(2)
    semaphore.release()


if __name__ == "__main__":
  semaphore = threading.BoundedSemaphore(5) # 创建信号量,并设置最多同时只能有5个线程可对代码并发操作。同时启动线程计数器
  threads = []
  for t in range(20):
    threads.append(MyThread())
  for i in threads:
    i.start()
  for j in threads:
    j.join()
  print("this is end!")
'''

'''
#********条件锁使用************
# 通过自定义类方式创建了一个线程:自定义的类必须有父类threading.Thread,必须有run(self)。此方法内容为要执行的逻辑代码
class Producer(threading.Thread):
  def run(self):
    global L
    while True:
      val = randint(0,100)
      if lock_con.acquire(): # 启动锁
        print("面包师%s生产了一个%s的包子放在了%s中"%(self.name, str(val),L))
        L.append(val)
        lock_con.notify() # 知在wait()状态的锁可以开始执行了。即激活作用!
        lock_con.release()
        time.sleep(3)


class Consumer(threading.Thread):
  def run(self):
    global L
    while True:
      lock_con.acquire() # 启动锁
      if len(L) == 0:
        lock_con.wait() # 释放锁并进入阻塞状况,等待notify激活后重新从acquire开始执行;
      print("客户%s吃掉了1个%s的包子"%(self.name,L[0]))
      del L[0]
      lock_con.release() # 释放锁
      time.sleep(0.25)

if __name__ == "__main__":
  L = [] # 放生产完的包子
  lock_con = threading.Condition() #创建一个条件锁:方便不同线程之间沟通
  threads = [] # 放所有线程名称的列表
  for t in range(5):
    threads.append(Producer()) # 创建5个线程,对应5个生产者对象---Producer()通过类方式创建了一个线程
  threads.append(Consumer())
  for i in threads:
    i.start()
  for j in threads:
    j.join()

'''

posted @ 2019-01-07 16:11  挖坑达人  阅读(11)  评论(0编辑  收藏  举报