Python进阶:进程的状态及基本操作

Posted 黑马程序员官方

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python进阶:进程的状态及基本操作相关的知识,希望对你有一定的参考价值。

文章目录


一、进程以及状态

  • 进程:资源分配的基本单位,也是线程的容器

  • 进程的状态:

    * 新建

    * 就绪

    * 运行

    * 等待

    * 死亡

二、[重点]进程-基本使用

  • 进程使用的步骤:

    • 导入模块

      import multiprocessing

    • 创建子进程对象

      process_obj = multiprocessing.Process(target=work1)

    • 启动子进程

      process_obj.start()

三、[重点]进程-名称、PID

  • 获取进程的名称

    multiprocessing.current_process()

    设置名称:

    multiprocessing.Process(target=xxxx, name=“进程名称”)

  • 获取进程的编号

    1. multiprocessing.current_process().pid
    2. os.getpid()
  • 获取进程的父id

    os.getppid()

  • 结束进程

    Kill -9 进程的编号

四、[重点]进程-参数传递、全局变量问题

  • 进程的参数传递

    • args 元组

    • kwargs 字典

    • 混合args 和 kwargs

          # 1)使用 args 传递元组
          # 2)使用 kwargs 传递字典
          # 3)混合使用 args 和 kwargs
          # process_obj = multiprocessing.Process(target=work1, args=(10, 100,1000))
          # process_obj = multiprocessing.Process(target=work1, kwargs="c": 1000, "a": 10, "b": 100)
          process_obj = multiprocessing.Process(target=work1, args=(10, ), kwargs="c": 1000, "b": 100)
      
      
  • 进程间共享全局变量的问题

    进程间是不能够共享全局变量

    底层原理:子进程会复制主进程的资源到内部运行

五、[重点]进程-守护主进程

  • 进程守护: 子进程和主进程的一种约定,当主进程结束的时候,子进程也随之结束

    process_obj.daemon = True

  • 结束子进程

        # terminate() 终止子进程的执行
        process_obj.terminate()
    

六、进程、线程对比

  • 进程和线程的对比
    • 进程是资源分配的基本单位,线程是CPU调度的基本单位
    • 进程运行需要独立的内存资源, 线程需要到的是必不可少的一点资源
    • 进程切换慢,线程切换更快
    • 线程不能独立运行,必须运行在进程中(进程能提供资源)
    • CPU密集型 进程优先, I/O 密集型使用线程
    • 程序更稳定进程,线程相比较不够稳定
  • 不是非此即彼,而是组合使用

七、[重点]消息队列-基本操作

  • 消息队列的学习的目的:为了实现进程间的通信

  • 队列的创建:

    • 导入模块 multiprocessing
    • multiprocessing.Queue(5) # 队列长度为5
  • 队列的操作:

    • 放入值 queue.put(值) —>从队列尾部放入值

    • 取值: queue.get() --> 从队列头部取值

    • xxxx_nowait() 方式

      • 放入值 put_nowait() 特点:队列未满,同put() 但是队列已满,会报错,不等待
      • 取值 get_nowait() 特点:队列未空,同get() 但是队列已空,会报错,不等待

八、消息队列-常见判断

  • 常见的判断
    • full() 判断是否已满
    • empty() 判断是否为空
  • 取出队列中消息的数量
    • qsize()

九、[重点]Queue实现进程间通信

  • 思路:利用队列在两个进程间进行传递,进而实现数据共享
    • write_queue(queue)
    • read_queue(queue)
    • 创建一个空队列
    • 把空队列作为参数,先把队列传递给写进程,然后把队列再传递给读进程
  • join() 优先让一个进程先执行完成,另外一个进程才能启动

十、[重点]进程池Pool

  • 进程池:是一个进程的容器,可以自动帮我们创建指定数量的进程,并且管理进程及工作

    • 创建方法:

      1. 导入模块

      2. 创建进程池

        pool = multiprocessing.Pool(3)

    • 工作方式:

      • 同步方式:

        pool.apply(函数名,(参数1,参数2,…))

        进程池中的进程,一个执行完毕后另外一个才能执行,多个进程执行有先后顺序

      • 异步方式:

        pool.apply_async(函数名,(参数1,参数2,…))

        进程池中的进程,多个进程同时执行,没有先后顺序

        1) 进程池要 close() 表示不再接受新的任务

        pool.close()

        2)还要join() 表示让主进程等待进程池执行结束后再退出

        pool.join()

十一、进程池中的Queue

  • 获取方法:

        # 1、创建进程池
        pool = multiprocessing.Pool(2)
    
        # 2、创建进程池中的队列
        queue = multiprocessing.Manager().Queue(5)
    
  •  # apply_async() 返回值 ApplyResult对象,该对象由一个 wait() 的方法
        # wait() 方法类似join() 表示先让当前进程执行完毕,后续进程才能启动
        result = pool.apply_async(write_queue, (queue, ))
        result.wait()
    
        pool.apply_async(read_queue, (queue, ))
        # close()表示不再接收新的任务
        pool.close()
        # 主进程会等待进程池执行结束后再退出
        pool.join()
    

十二、案例:文件夹copy器(多进程版)

  • 思路:

    ./test/ ---------> /home/demo/Desktop/test/

    思路:
    1、定义变量,保存源文件夹、目标文件夹所在的路径
    2、在目标路径创建新的文件夹
    3、获取源文件夹中的所有的文件(列表)
    4、遍历列表,得到所有的文件名
    5、定义函数,进行文件拷贝

    文件拷贝函数:
    参数: 源文件夹路径 目标文件夹路径 文件名
    1、拼接源文件和目标文件的具体路径
    2、打开源文件,创建目标文件
    3、读取源文件的内容,写入到目标文件中 (while)

  • 进程池拷贝文件

     # 创建进程池
        pool = multiprocessing.Pool(3)
    
        # 4、遍历列表,得到所有的文件名
        for file_name in file_list:
            # print(file_name)
            # 5、定义函数,进行文件拷贝
            # copy_work(source_dir, dest_dir, file_name)
            pool.apply_async(copy_work, (source_dir, dest_dir, file_name))
        # close() 不再接收新的任务
        pool.close()
        # 让主进程等待进程池结束后在退出
        pool.join()
    
  • 创建文件夹

    os.mkdir(路径)

  • 获取文件夹中的内容

    os.listdir(路径)

十三、[重点]可迭代对象及检测方法

  • 可迭代对象

    # 1、可遍历对象就是可迭代对象
    # 2、列表、元组、字典、字符串都是可迭代对象
    # 3、100 和 自定义myclass 默认都是不可以迭代的
    # 4、myclass 对象所属的类 MyClass 如果包含了 __iter__() 方法,此时
    #    myclass就是一个可迭代对象
    # 5、可迭代对象的本质:对象所属的类中包含了 __iter__() 方法
    
  • 可迭代对象的检测:

    # 6、检测一个对象是否可以迭代,用 isinstance() 函数检测
    

十四、[重、难点]迭代器及其使用方法

  • 迭代器的作用:

    1) 记录当前迭代的位置 2)配合next() 获取可迭代对象的下一个元素值

  • 获取迭代器

    iter(可迭代对象)

  • 获取可迭代对象的值

    next(迭代器)

  • for循环的本质:

    1)通过 iter(要遍历的对象) 获取要遍历的对象的迭代器
    2)next(迭代器)获取下一个元素
    3)帮我们捕获了 StopIteration 异常

  • 自定义迭代器类

    # 自定义迭代器类,满足2点
    # 1)必须含有 __iter__()
    # 2) 必须含有 __next__()
    
    class MyIterator(object):
        def __iter__(self):
            pass
    
        # 当 next(迭代器) 的时候,会自动调用该方法
        def __next__(self):
            pass
    

以上是关于Python进阶:进程的状态及基本操作的主要内容,如果未能解决你的问题,请参考以下文章

Python进阶第二篇多线程消息队列queue

Python装饰器与GIL锁解释

进程的描述与控制

python进阶03

进程三种基本状态

Android 进阶——性能优化之借助adb shell ps /top 指令详细分析进程