zoukankan      html  css  js  c++  java
  • python全栈开发day32-进程创建,进程同步,进程间的通信,进程池

    一、内容总结

      1.进程创建

        1)   Process:两种创建一个新进程的方法:

            1.实例化Process,通过args=(,)元组形式传参,2创建类继承Process,类初始化的时候传参数

        2)  p.join(),阻塞主进程,执行完p进程后,释放

        3)   守护进程 ,守护主程序代码执行完毕,p.daemon = True     

    import time
    from multiprocessing import Process
    
    
    def func():
        while True:
            print('is alive')
            time.sleep(0.5)
    
    
    def wahaha():
        i = 0
        while i < 5:
            print('第%s秒'%i)
            time.sleep(1)
            i += 1
    
    
    if __name__ == '__main__':
        p2 = Process(target=wahaha)
        p2.start()
        p1 = Process(target=func)
        p1.daemon = True   # 设置p1为守护进程
        p1.start()
        time.sleep(3)
        print('主进程')
        p2.join()   # 守护进程会等待子进程结束后才结束守护
    守护进程代码

        4)  p.terminate() 不会立即结束,会等待主进程回收资源等

     # python和进程
        # multiprocessing模块
        # 主进程
        # 父子进程
            # 父进程需要等待子进程执行结束之后才结束
                # 负责回收子进程的一些资源
            # 进程与进程之间数据隔离
                # 子进程可以在创建之初接收参数
                # 但是不能直接返回值
            # 异步 父子进程之间的工作是互不干扰的
        # 开启一个子进程
            # multiprocessing.Process
            # 第一种方式
                # 实例化创建一个进程
                # start开启一个进程
            # 第二种方式
                # 采用面向对象的形式来创建进程
                    # 继承Process
                    # 在init处传参数
                    # 重写run方法
        # 子进程的控制
            # join           

      2.进程的同步

        1)、锁 Lock

          加锁,维护了数据的安全,但降低了程序的效率,但所有的效率都必须建立在数据安全的基础上;

          但凡涉及到并发编程我们都要考虑共享数据的安全性,我需要在并发部分对数据操作格外小心,

          如果涉及到数据的不安全就要加锁控制。

    #  查票的例子
    import os,time
    from multiprocessing import Lock,Process
    import json
    
    
    def search(i):
        with open('db') as f:
            ticket_count = json.load(f)
            print('%s查到了还剩余:%s张余票!' % (i,ticket_count['count']))
    
    
    def buy(i):
        with open('db') as f:
            ticket_count = json.load(f)
            time.sleep(0.2)     # 模拟请求数据库数据网络传输时延
        if ticket_count['count'] > 0:
            ticket_count['count'] -= 1
            print('%s号买到了车票!'% i)
            time.sleep(0.2)     # # 模拟写入数据库数据网络传输时延
            with open('db', 'w') as f:
                json.dump(ticket_count, f)
    
    def get_ticket(lock, i):
        search(i)
        with lock: buy(i)
    # 两种加锁方式
    #
    # def get_ticket(lock, i):
    #     search(i) # 查票不用加锁,都可以查
    #     lock.acquire()
    #     buy(i) # 买票加锁
    #     lock.release()
    
    
    if __name__ == '__main__':
        lock = Lock()
        for i in range(10):
            p = Process(target=get_ticket,args=(lock,i))
            p.start()
    查车票的例子

        lock内部实现进程间的通信,使得谁acquire了锁,谁realease了在多个拥有lock参数子进程中透明。

        2)、信号量 Semaphore 锁+计数器

          

    # 4人KTV的例子
    
    # def ktv(sema,i):
    #     sema.acquire()
    #     print('%s 走进ktv!' % i)
    #     time.sleep(random.randint(1,5))
    #     print('%s 走出KTV!!!'% i)
    #     sema.release()
    
    
    def ktv(sema,i):
        with sema:
            print('%s 走进ktv!' % i)
            time.sleep(random.randint(1,5))
            print('%s 走出KTV!!!'% i)
    
    
    if __name__ == '__main__':
        sema = Semaphore(4)
        for i in range(10):
            p = Process(target=ktv, args=(sema, i))
            p.start()
    4人KTV的例子

        3)、事件Event

           控制子进程阻塞还是执行的一个机制:

          wait方法:

            如果is_set() 标志位为False,则阻塞 wait(n)可以设置阻塞n秒后继续执行,但标志位不会改变,还是False

                           如果is_set() 标志位为True,效果相当于pass

          控制标志:

            is_set():判断标志位状态

            set():设置标志位为True

            clear():设置标志位False

                         

    import time, random
    from multiprocessing import Process,Event
    
    e = Event()
    # print(e.is_set()) 会打印12次,数数吧哈哈
    
    def traffic_light(e):
        print('33[1;31m红灯亮了33[0m')
        while True:
            time.sleep(2)
            if e.is_set():
                print('33[1;31m红灯亮了33[0m')
                e.clear()
            else:
                print('33[1;32m绿灯亮了33[0m')
                e.set()
    
    
    def car(e, i):
        if not e.is_set():
            print('car%s 在等待红灯' % i)
            e.wait()
        print('car%s 通过' % i)
    
    
    if __name__ == '__main__':
        e = Event()
        traffic_light1 = Process(target=traffic_light, args=(e,))
        traffic_light1.daemon = True
        traffic_light1.start()
        li = []
        for i in range(10):
            p = Process(target=car, args=(e, i))
            p.start()
            li.append(p)
            time.sleep(random.randint(0, 3))
        for p in li:
            p.join()
        print('主程序结束!')
    事件红绿灯的例子

      3.进程间的通信

        1.队列Queue

          # IPC 进程之间的通信

          empty():# 多进程的情况下 不准:

          full():# 多进程的情况下 不准:

          put():#队列慢 会引起程序的阻塞:

          get():#队列空 会引起程序的阻塞:

          put_nowait(): # 不会阻塞,但容易丢失数据

          get_nowait():# 不会阻塞,但满的话会报错

          

    from multiprocessing import Process,Queue
    
    def num(q,i):
        q.put({i:i**i})
    
    
    if __name__ == '__main__':
        q = Queue()
        for i in range(10):
            p = Process(target=num, args=(q,i))
            p.start()
    
        for j in range(10):
            print(q.get())
    利用Queue进行进程通信的例子

        2.管道

        3.Manager

      4.进程池

        pool

      

    二、预习和扩展

  • 相关阅读:
    linux中mysql,mongodb,redis,hbase数据库操作
    hbase数据库操作
    hdfs基本操作
    linux及hadoop基本操作
    创建有关hbase数据库的项目时所遇到的问题
    数据科学与大数据
    《TCP/IP详解卷1:协议》——第2章:链路层(转载)
    《TCP/IP详解卷1:协议》——第1章:概述(转载)
    深入理解计算机操作系统——第9章:缓存,存储器管理
    深入理解计算机操作系统——第9章:物理和虚拟寻址,地址空间
  • 原文地址:https://www.cnblogs.com/wuchenggong/p/9174688.html
Copyright © 2011-2022 走看看