zoukankan      html  css  js  c++  java
  • 进程间通信 IPC机制 生产者消费者模型 线程 创建线程的方式 和其他方法 守护线程 线程间通信 互斥锁

    进程间通信 

    队列和堆栈

      队列:先进先出     排队
      堆栈:先进后出     往衣柜里面放衣服

    from multiprocessing import Queue
    
    q = Queue(5)  # 括号内可以传参数  表示的是这个队列最大的存储数
    
    # 向队列中添加数据
    q.put(1)
    q.put(2)
    q.put(3)
    q.put(4)
    q.put(5)
    # q.put(6)  # 当队列满了之后   再次放入数据   不会报错  会在原地等待  直到队列中有数据被取走(阻塞态)
    
    # 取值    
    # full   判断队列是否满了  返回布尔值
    # empty   判断队列中数据是否为空   返回布尔值
    # get._nowait    取值   没有值的话不等地啊 直接报错
    print(q.get())
    print(q.get())
    print(q.full())  # False 判断队列是否满了  返回布尔值
    print(q.get())
    print(q.empty())  # False 判断队列中数据是否为空  返回布尔值
    print(q.get())
    print(q.get())
    print(q.full())  # True 判断队列是否满了
    print(q.get())  #当队列中的数据被取完之后   再次获取  程序会阻塞   直到有人往队列中放值
    # print(q.get_nowait())  # 取值  没有值不等待直接报错

    进程间通信IPC机制   

    from multiprocessing import Process,Queue
    
    def producer(q):
        q.put('hello')
    
    def consumer(q):
        print(q.get())
    
    
    
    if __name__ == '__main__':
        q = Queue()
        p = Process(target=producer,args=(q,))
        p.start()
    
        c = Process(target=consumer,args=(q,))
        c.start()
    
    
    '''
    子进程放数据  主进程获取数据
    两个子进程相互放  取数据
    
    '''

    生产者消费者模型   

    '''
    什么是生产者
        生产者: 生产/制造数据的
    什么是消费者
        消费者: 消费/处理数据的
    例子:生产者  做包子的
         消费者  买包子的
            1 做包子的远比买包子的多
            2 做包子的远比买包子的少
                供需不平衡的问题
    '''
    
    from multiprocessing import Process,Queue,JoinableQueue
    import random
    import time
    
    def producer(name,food,q):
        for i in range(10):
            data = '%s生产了%s%s'%(name,food,i)
            time.sleep(random.random())
            q.put(data)
            print(data)
    
    
    
    def consumer(name,q):
        while True:
            data = q.get()
            if data == None:
                break
            print('%s吃了%s'%(name,data))
            time.sleep(random.random())
            q.task_done()  # 告诉队列你已经从队列中取出一个数据  并且处理完毕了
    
    if __name__ == '__main__':
        # q = Queue
        q = JoinableQueue()
    
        p = Process(target=producer,args=('大厨egon','馒头',q))
        p1 = Process(target=producer,args=('跟班tank','生蚝',q))
        c = Process(target=consumer,args=('jason',q))
        c1 = Process(target=consumer,args=('吃货jerry',q))
        p.start()
        p1.start()
    
        c.daemon = True
        c1.daemon = True
    
        c.start()
        c1.start()
        p.join()
        p1.join()
    
        q.join()  # 等待队列中数据全部取出
        # q.put(None)
        # q.put(None)

    线程   

    什么是线程
    进程线程其实都是虚拟单位,都是用来帮助我们形象的描述某种事物
    进程:资源单位
    线程:执行单位
    范例:
    将内存比喻成工厂
    那么进程就相当于工厂里面的车间
    而你的线程就相当于车间里面的流水线
    ps: 每个进程都自带一个线程
    为什么要有线程
    开进程
    1 申请内存空间 消耗资源
    2 类似于'拷贝代码' 消耗资源
    开线程
    1 一个进程内可以起多个线程,并且线程与线程之间数据是共享的
    ps: 开启线程的开销要远远小于开启进程的开销
    如何用线程

    创建线程的方式   

    from threading import Thread
    import time
    
    
    def task(name):
        print('%s is running'%name)
        time.sleep(3)
        print('%s is over'%name)
    # 开线程不需要在__main__代码块内  但是习惯性的还是写在__main__代码块内
    
    t = Thread(target=task,args=('egon',))
    t.start()  #告诉操作系统 开辟一个线程   只不过线程的开销远远小于进程
    # 小到代码执行完毕  线程就已经开启了
    print('')
    第一种
    from threading import Thread
    import time
    class MyThread(Thread):
        def __init__(self,name):
            super().__init__()
            self.name = name
        def run(self):
            print('%s is running'%self.name)
            time.sleep(3)
            print('%s is over'%self.name)
    
    t = MyThread('egon',)
    t.start()
    print('')
    第二种

    线程对象其他方法 

    from threading import Thread,current_thread,active_count
    import time
    import os
    
    
    def task(name,i):
        print('%s is running'%name)
        # print('current_Thread:',current_thread().name)
        # print('子',os.getpid())
        time.sleep(i)
        print('%s is over'%name)
    # 开线程不需要在__main__代码块内  但是习惯性的还是写在__main__代码块内
    
    t = Thread(target=task,args=('egon',2))
    t1 = Thread(target=task,args=('jason',1))
    t.start()  #告诉操作系统 开辟一个线程   只不过线程的开销远远小于进程
    # 小到代码执行完毕  线程就已经开启了
    t1.start()
    print('当前正在活跃的线程数',active_count())
    print('')
    # print('主current_Thread:',current_thread().name)
    # print('主',os.getpid())

    守护线程 

    from threading import Thread,current_thread
    import time
    
    
    
    def task(i):
        print(current_thread().name)
        time.sleep(i)
        print('GG')
    # for i in range(3):
    #     t = Thread(target=task,args=(i,))
    #     t.start()
    
    t = Thread(target=task,args=(1,))
    t.daemon = True
    t.start()
    print('')
    # 主线程运行结束之后需要等待子线程结束才能结束呢?
    '''
    主线程的结束意味着进程的结束
    主线程必须等待其他非守护线程的结束才能结束
    (意味着子线程在运行程序的时候需要使用进程中的资源,
     而主线程一旦结束了资源也就销毁了)
    '''

     

    线程间通信   

    from threading import Thread
    
    money = 666
    
    def task():
        global money
    
        money = 999
    
    t = Thread(target=task)
    t.start()
    t.join()
    print(money)

    互斥锁  

    from threading import Thread,Lock
    import time
    
    
    n = 100
    def task(mutex):
        global n
        mutex.acquire()
        tem = n
        time.sleep(0.1)
        n = tem - 1
        mutex.release()
    
    t_list = []
    mutex = Lock()
    for i in range(100):
        t = Thread(target=task,args=(mutex,))
        t.start()
        t_list.append(t)
    for t in t_list:
        t.join()
    print(n)

    小练习

    from threading import Thread
    from multiprocessing import Process
    import time
    
    
    def foo():
        print(123)
        time.sleep(1)
        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-------")
    
    
    
    输出结果
    123
    456
    main-------   
    # 3秒后输出
    end123
    end456
  • 相关阅读:
    Java XML的总结(一)
    golang两个协程交替打印1-100的奇数偶数
    nat类型探测方法(排除法)
    janus-gateway 在macOS上的编译部署
    性能测试-并发和QPS
    基于etcd的Rabbitmq队列订阅负载均衡
    【python学习笔记】10.充电时刻
    【python学习笔记】9.魔法方法、属性和迭代器
    【python学习笔记】8.异常
    【python学习笔记】7.更加抽象
  • 原文地址:https://www.cnblogs.com/xuzhaolong/p/11341027.html
Copyright © 2011-2022 走看看