zoukankan      html  css  js  c++  java
  • 进程之间通信、线程

    • 去幕布 >>
    • 进程之间通信IPC机制
      • 队列:先进先出(队列=管道+锁)
        full、get_nowait、empty 都不适用于多进程的情况
      • 队列 的方法演示
        from multiprocessing import Queue
        ​
        q = Queue(3)  # 括号内可以传参数 表示的是这个队列的最大存储数
        # 往队列中添加数据
        q.put(1)
        q.put(2)
        print(q.full())  # 判断队列是否满了
        q.put(3)
        print(q.full())
        # q.put(4)  # 当队列满了之后,再放入数据 不会报错,会原地等待 直到队列中有数据被取走(阻塞态)
        print(q.get())
        print(q.get())
        print(q.empty())  # 判断队列中的数据是否取完
        print(q.get())
        print(q.empty())
        # print(q.get_nowait())  # 取值 没有值不等待直接报错(queue.Empty)
        print(q.get())  # 当队列中的数据被取完之后,再次获取,程序会阻塞 直到有人往队列中放入值
        
        
        ​​​
        '''执行结果
        False
        True
        1
        2
        False
        3
        True
        ​​'''​​​
        View Code
      • 进程间通信(IPC,InterProcess Communication)
        子进程放数据,主进程获取数据
        两个子进程相互 放 取数据
      • IPC 之队列方式 的代码演示
        from multiprocessing import Process,Queue
        ​
        def producer(q):
            q.put('hello GF~')
        def consumer(q):
            print(q.get())
        ​
        if __name__ == '__main__':
            q = Queue()
            p = Process(target=producer,args=(q,))
            c = Process(target=consumer, args=(q,))
            p.start()
            c.start()
        
        ​​
        '''执行结果:
        hello GF~
        '''​​​
        View Code
      • 生产者消费者模型
        生产者:生产/制造数据的
        消费者:消费/处理数据的
        例子:做包子的,买包子的
                1.做包子远比买包子的多
                2.做包子的远比包子的少
                供需不平衡的问题
        
        进程中的应用:
        将两个函数实例化为进程,通过队列通信,
        ​通过Joinable​​​Queue模块确定队列中的值是否取完
        理解
      • 生产者消费者模型 在进程中的应用
        from multiprocessing import Process,Queue,JoinableQueue
        import random
        import time
        ​
        def producer(name,food,q):
            for i in range(1):
                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()
                print('%s吃了%s'%(name,data))
                time.sleep(random.random())
                q.task_done()  # 告诉队列你已经从队列中取出了一个数据 并且处理完毕了
        if __name__ == '__main__':
            q = JoinableQueue()
            p = Process(target=producer,args=('大厨egon','馒头',q))
            p1 = Process(target=producer,args=('跟班tank','生蚝',q))
            c = Process(target=consumer,args=('许兆龙',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()  # 等到队列中数据全部取出
        
        ​​
        '''执行结果:
        跟班tank生产的生蚝0
        吃货jerry吃了跟班tank生产的生蚝0
        大厨egon生产的馒头0
        许兆龙吃了大厨egon生产的馒头0
        Process finished with exit code 0
        ​​'''
        View Code
    • 线程
      什么是线程
          进程线程其实都是虚拟单位,都是用来帮助我们形象的描述某种事物
      ​
          进程:资源单位
          线程:执行单位
              将内存比如成工厂
              那么进程就相当于是工厂里面的车间
              而你的线程就相当于是车间里面的流水线
          ps:每个进程都自带一个线程,线程才是真正的执行单位,进程只是在线程运行过程中
          提供代码运行所需要的资源
      ​
      为什么要有线程
          开进程
              1.申请内存空间  耗资源
              2."拷贝代码"    耗资源
          开线程
              一个进程内可以起多个线程,并且线程与线程之间数据是共享的
          ps:开启线程的开销要远远小于开启进程的开销
      理解
      • 创建线程的两种方式
        # 第一种方式(直接调用Threading模块的Thread)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('')
        ​​
        '''执行结果:
        ​​egon is running
        主
        egon is over
        '''​
        ​​​
        
        
        # 第二种方式(自定义Tread方法)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('')
        ​​​​
        '''执行结果:
        ​​egon is running
        主
        egon is over
        '''​​
        View Code
      • 线程对象及其他方法
        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',1))
        t1 = Thread(target=task,args=('jason',2))
        t.start()  # 告诉操作系统开辟一个线程  线程的开销远远小于进程
        t1.start()  # 告诉操作系统开辟一个线程  线程的开销远远小于进程
        t1.join()  # 主线程等待子线程运行完毕
        print('当前正在活跃的线程数',active_count())
        # 等到代码执行完 线程就已经开启了
        print('')
        ​
        ​'''执行结果:
        ​egon is running
        jason is running
        egon is over
        jason is over
        当前正在活跃的线程数 1
        主
        Process finished with exit code 0
        '''
        View Code
      • 守护线程
        主线程的结束也就意味着进程的结束
        主线程必须等待其他非守护线程的结束才能结束
        (意味子线程在运行的时候需要使用进程中的资源,而主线程一旦结束了资源也就销毁了)
        理解
      • 守护线程代码示例
        from threading import Thread,current_thread
        import time
        ​
        def task(i):
            print(current_thread().name)
            time.sleep(i)
            print('GG')
        ​
        t = Thread(target=task,args=(1,))
        t.daemon = True
        t.start()
        print('')
        ​
        '''执行结果:
        Thread-1
        主
        ​'''​​
        View Code
      • 线程之间通信
        from threading import Thread
        ​
        money = 666
        def task():
            global money
            money = 999
        ​
        t = Thread(target=task)
        t.start()
        t.join()
        print(money)
        ​
        '''执行结果:
        999
        '''
        View Code
      • 互斥锁在线程中的应用(将并行编程串行)
        from threading import Thread,Lock
        import time
        ​
        n = 10
        def task(mutex):
            global  n
            mutex.acquire()
            tmp = n
            time.sleep(0.1)
            n = tmp - 1
            mutex.release()
        ​
        t_list = []
        mutex = Lock()
        for i in range(10):
            t = Thread(target=task,args=(mutex,))
            t.start()
            t_list.append(t)
        for t in t_list:
            t.join()
        ​
        print(n)
        
        '''执行结果:
        0
        '''​​​​​
        View Code
  • 相关阅读:
    apt-get
    微博
    字符串操作
    fly
    Oracle数据库只Dual表
    如何配置一个Oracle服务
    排序算法
    排序算法
    排序算法
    ArcEngine几个空间操作
  • 原文地址:https://www.cnblogs.com/buzaiyicheng/p/11341201.html
Copyright © 2011-2022 走看看