• 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()
  • 相关阅读:
    【转】Asp.net页面的生命周期
    指定.net的httprequest http协议版本为1.0
    查看oracle中被锁的对象(表...)
    网友整理的Flex开源项目
    oracle中用profile限定用户资源
    (转)让你受益终身的10个Word实用技巧
    磁盘阵列卡
    Nmap扫描器的使用
    最简单的数据库连接,asp连接access数据库
    网络经典命令行
  • 原文地址:https://www.cnblogs.com/zhuqihui/p/10976584.html
Copyright © 2020-2023  润新知