• python 多进程,实际上都没有运行,sleep


     进程以及状态

    1. 进程
    程序:例如xxx.py这是程序,是一个静态的

    进程:一个程序运行起来后,代码+用到的资源 称之为进程,它是操作系统分配资源的基本单元。

    不仅可以通过线程完成多任务,进程也是可以的

    2. 进程的状态
    工作中,任务数往往大于cpu的核数,即一定有一些任务正在执行,而另外一些任务在等待cpu进行执行,因此导致了有了不同的状态

    就绪态:运行的条件都已经慢去,正在等在cpu执行
    执行态:cpu正在执行其功能
    等待态:等待某些条件满足,例如一个程序sleep了,此时就处于等待态

    linux上进程有5种状态: 
    1. 运行(正在运行或在运行队列中等待) 
    2. 中断(休眠中, 受阻, 在等待某个条件的形成或接受到信号) 
    3. 不可中断(收到信号不唤醒和不可运行, 进程必须等待直到有中断发生) 
    4. 僵死(进程已终止, 但进程描述符存在, 直到父进程调用wait4()系统调用后释放) 
    5. 停止(进程收到SIGSTOP, SIGSTP, SIGTIN, SIGTOU信号后停止运行运行) 

    ps工具标识进程的5种状态码: 
    D 不可中断 uninterruptible sleep (usually IO) 
    R 运行 runnable (on run queue) 
    S 中断 sleeping 
    T 停止 traced or stopped 
    Z 僵死 a defunct ("zombie") process 

    线程与进程

    线程与进程是操作系统里面的术语,简单来讲,每一个应用程序都有一个自己的进程。
    操作系统会为这些进程分配一些执行资源,例如内存空间等。
    在进程中,又可以创建一些线程,他们共享这些内存空间,并由操作系统调用,
    以便并行计算。

    32位系统受限于总线宽度,单个进程最多能够访问的地址空间
    只有4G,利用物理地址扩展(PAE)
    技术,可以让CPU访问超过4G内存。但是在单个进程还是只能访问4G
    空间,PAE的优势是可以让不同进程累计使用的内存超过4G。
    在个人电脑上,还是建议使用64位系统,便于使用大内存
    提升程序的运行性能。

    多线程编程

    线程的状态

    创建线程之后,线程并不是始终保持一个状态。其状态大概如下:

    • New 创建。
    • Runnable 就绪。等待调度
    • Running 运行。
    • Blocked 阻塞。阻塞可能在 Wait Locked Sleeping
    • Dead 消亡

    线程的类型

    线程有着不同的状态,也有不同的类型。大致可分为:

    • 主线程
    • 子线程
    • 守护线程(后台线程)
    • 前台线程

    python的GIL

    GIL即全局解释器锁,它使得python的多线程无法充分利用
    多核的优势,但是对于I/O操作频繁的爬虫之类的程序,
    利用多线程带来的优势还是很明显的。
    如果要利用多核优势,还是用多进程吧。

    https://tracholar.github.io/wiki/python/python-multiprocessing-tutorial.html

     可以直接使用top命令后,查看%MEM的内容。可以选择按进程查看或者按用户查看,如想查看oracle用户的进程内存使用情况的话可以使用如下的命令:

     (1)top

      top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器

      可以直接使用top命令后,查看%MEM的内容。可以选择按进程查看或者按用户查看,如想查看oracle用户的进程内存使用情况的话可以使用如下的命令:
      $ top -u oracle

    内容解释:

      PID:进程的ID
      USER:进程所有者
      PR:进程的优先级别,越小越优先被执行
      NInice:值
      VIRT:进程占用的虚拟内存
      RES:进程占用的物理内存
      SHR:进程使用的共享内存
      S:进程的状态。S表示休眠,R表示正在运行,Z表示僵死状态,N表示该进程优先值为负数
      %CPU:进程占用CPU的使用率
      %MEM:进程使用的物理内存和总内存的百分比
      TIME+:该进程启动后占用的总的CPU时间,即占用CPU使用时间的累加值。
      COMMAND:进程启动命令名称

      常用的命令:

      P:按%CPU使用率排行
      T:按MITE+排行
      M:按%MEM排行

    (2)pmap

      可以根据进程查看进程相关信息占用的内存情况,(进程号可以通过ps查看)如下所示:
      $ pmap -d 14596

     

    进程

    python中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU的资源,在python中大部分情况需要使用多进程。

    Python提供了非常好用的多进程包multiprocessing,只需要定义一个函数,Python会完成其他所有事情。

    借助这个包,可以轻松完成从单进程到并发执行的转换。

    multiprocessing支持子进程、通信和共享数据、执行不同形式的同步,提供了Process、Queue、Pipe、Lock等组件。

    ---------------------

    1.https://segmentfault.com/q/1010000011117956
    该题主描述了同样的问题。我觉得比较有意义的回答是这个

            multiprocessing.Pool 只是用来启动多个进程而不是在每个core上启动一个进程。换句话说Python解释器本身不会去在每个core或者processor去做负载均衡。这个是由操作系统决定的。

            如果你的工作特别的计算密集型的话,操作系统确实会分配更多的core,但这也不是Python或者代码所能控制的或指定的。
            multiprocessing.Pool(num)中的num可以很小也可以很大,比如I/O密集型的操作,这个值完全可以大于cpu的个数。
            硬件系统的资源分配是由操作系统决定的,如果你希望每个core都在工作,就需要更多的从操作系统出发了~

    在后续的回答中给出了一个stackoverflow里面的此类问题介绍

    实验
    实验环境:4C8G
    1.工作任务设置成计算密集型
    四个任务被均分到四个核上,顺利运行

    2.计算密集型+每个进程小内存消耗
    四个任务被均分到四个核上,顺利运行

    3.计算密集型+每个进程大内存消耗
    计算机卡死


    ---------------------

    2018-12-18  今天好像找到问题了的原因了:

    问题1:

    因为进程间不同享全局变量,所以我定义的全局变量df_list,在最后依旧是初始状态df_list = [ ]

    实例:

    # -*- coding:utf-8 -*-
    from multiprocessing import Process
    import os
    import time
     
    nums = [11, 22]
     
    def work1():
        """子进程要执行的代码"""
        print("in process1 pid=%d ,nums=%s" % (os.getpid(), nums))
        for i in range(3):
            nums.append(i)
            time.sleep(1)
            print("in process1 pid=%d ,nums=%s" % (os.getpid(), nums))
     
    def work2():
        """子进程要执行的代码"""
        print("in process2 pid=%d ,nums=%s" % (os.getpid(), nums))
     
    if __name__ == '__main__':
        p1 = Process(target=work1)
        p1.start()
        p1.join()
     
        p2 = Process(target=work2)
        p2.start()
    

      

    问题2:问题在于,多进程可以启动,但是,所有子进程都处于等待状态

    可能是资源的问题。内存资源不够,所以无法同时运行,只能等待!这只是猜想了。

    参考:https://blog.csdn.net/u013735511/article/details/80079373

              https://blog.csdn.net/xlengji/article/details/81165370

  • 相关阅读:
    210111做个期望值低的人
    error_1 springboot `com.mysql.jdbc.Driver'问题
    error_2 springboot mysql时区设置
    17_springboot Restful风格
    15_JSON springboot
    13_springboot文件上传
    12_springboot myBatis crud
    11_springboot JPA crud
    Swagger导出MarkDown
    Docker 使用中的一些问题
  • 原文地址:https://www.cnblogs.com/Allen-rg/p/10121701.html
Copyright © 2020-2023  润新知