zoukankan      html  css  js  c++  java
  • 守护进程补充,线程,递归锁及信号量


    一、守护进程应用实例

    import time
    import random
    from multiprocessing import Process,JoinableQueue

    def consumer(name,q):
    while True:
    res=q.get()
    if res is None:break
    time.sleep(random.randint(1,3))
    print('33[46m消费者===》%s 吃了 %s33[0m' %(name,res))
    q.task_done()

    def producer(name,q,food):
    for i in range(5):
    time.sleep(random.randint(1,2))
    res='%s%s' %(food,i)
    q.put(res)
    print('33[45m生产者者===》%s 生产了 %s33[0m' %(name,res))

    if __name__ == '__main__':
    #1、共享的盆
    q=JoinableQueue()

    #2、生产者们
    p1=Process(target=producer,args=('egon',q,'包子'))
    p2=Process(target=producer,args=('刘清政',q,'泔水'))
    p3=Process(target=producer,args=('杨军',q,'米饭'))

    #3、消费者们
    c1=Process(target=consumer,args=('alex',q))
    c2=Process(target=consumer,args=('梁书东',q))
    c1.daemon=True
    c2.daemon=True

    p1.start()
    p2.start()
    p3.start()
    c1.start()
    c2.start()

    # 确定生产者确确实实已经生产完毕
    p1.join()
    p2.join()
    p3.join()
    # 在生产者生产完毕后,拿到队列中元素的总个数,然后直到元素总数变为0,q.join()这一行代码才算运行完毕
    q.join()
    #q.join()一旦结束就意味着队列确实被取空,消费者已经确确实实把数据都取干净了
    print('主进程结束')

    二、线程

    1、什么是线程
    线程指的是一条流水线的工作过程
    进程根本就不是一个执行单位,进程其实是一个资源单位
    一个进程内自带一个线程,线程才是执行单位

    2、进程VS线程
    1、同一进程内的线程们共享该进程内资源,不同进程内的线程资源肯定是隔离的
    2、创建线程的开销比创建进程要小的多

    注:线程因资源消耗较少所以开启速度较快

    开启线程方式一:
    from multiprocessing import Process
    from threading import Thread
    import time

    def task(name):
    print('%s is running' %name)
    time.sleep(3)

    if __name__ == '__main__':
    t=Thread(target=task,args=('egon',))
    t.start()
    print('主线程')

    开启线程方式二:

    from multiprocessing import Process
    from threading import Thread
    import time

    class MyThread(Thread):
    def run(self):
    print('%s is running' %self.name)
    time.sleep(3)

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


    线程对象的其他方法:
    from threading import Thread,current_thread,active_count,enumerate
    import time,os

    def task():
    print('%s is running' %current_thread().name) #打印线程名
    time.sleep(3)

    if __name__ == '__main__':
    t1=Thread(target=task,name='第一个线程') #为线程命名
    t2=Thread(target=task,)
    t3=Thread(target=task,)
    t1.start()
    t2.start()
    t3.start()

    # print(t1.is_alive())
    print(active_count()) #计算总共运行了多少个线程
    print(enumerate()) #列出所有正在运行的线程
    print('主线程',current_thread().name)

    守护线程:

    示例代码:
    from threading import Thread
    import time
    def foo():
    print(123)
    time.sleep(5)
    print("end123")

    def bar():
    print(456)
    time.sleep(3)
    print("end456")

    if __name__ == '__main__':

    t1=Thread(target=foo)
    t2=Thread(target=bar)

    t1.daemon=True
    t1.start()
    t2.start()
    print("main-------")

    与进程不同守护线程结束运行时间为其它所有进程结束之后才会执行

    三、递归锁
    死锁就是在程序中有两个或者两个以上的互斥锁,互相锁死导致程序卡死,在程序中应尽量避免使用互斥锁。
    递归锁也是解决死锁问题一种方法,在程序中线程每次拿到锁都会把所有锁计数加一,每次丢掉锁计数减一,
    只要锁的计数不为零别的程序就无法加锁

    from threading import Thread,Lock,RLock
    import time

    mutexA=mutexB=RLock()

    class MyThread(Thread):
    def run(self):
    self.f1()
    self.f2()

    def f1(self):
    mutexA.acquire()
    print('%s 拿到了A锁' %self.name)

    mutexB.acquire()
    print('%s 拿到了B锁' %self.name)
    mutexB.release()

    mutexA.release()

    def f2(self):
    mutexB.acquire()
    print('%s 拿到了B锁' %self.name)
    time.sleep(0.1)

    mutexA.acquire()
    print('%s 拿到了A锁' %self.name)
    mutexA.release()

    mutexB.release()


    if __name__ == '__main__':
    for i in range(10):
    t=MyThread()
    t.start()

    print('主')

    三、信号量

    互斥锁 在同时只允许一个人更改数据而信号量Semaphore 则是允许指定数量的线程更改数据,指定多少个线程可以更改,
    后续线程只能等待前面线程释放后才能加锁。


    示例代码:
    from threading import Thread,Semaphore,current_thread
    import time,random

    sm=Semaphore(5)

    def go_wc():
    sm.acquire()
    print('%s 上厕所ing' %current_thread().getName())
    time.sleep(random.randint(1,3))
    sm.release()

    if __name__ == '__main__':
    for i in range(23):
    t=Thread(target=go_wc)
    t.start()







  • 相关阅读:
    hdoj 2803 The MAX【简单规律题】
    hdoj 2579 Dating with girls(2)【三重数组标记去重】
    hdoj 1495 非常可乐【bfs隐式图】
    poj 1149 PIGS【最大流经典建图】
    poj 3281 Dining【拆点网络流】
    hdoj 3572 Task Schedule【建立超级源点超级汇点】
    hdoj 1532 Drainage Ditches【最大流模板题】
    poj 1459 Power Network【建立超级源点,超级汇点】
    hdoj 3861 The King’s Problem【强连通缩点建图&&最小路径覆盖】
    hdoj 1012 u Calculate e
  • 原文地址:https://www.cnblogs.com/zhaodafa/p/8952420.html
Copyright © 2011-2022 走看看