• 进程池,线程的理论,Threading.Thread来创建线程


    进程 :

      进程池

    线程 :

      理论

      threading.Thread来创建线程

    1 . 下面代码是同步请求的

    import os,time

    from multiprocessing import Pool

    def wahaha()

      time.sleep(1)

      print(os.getpid())

      return True

    if __name__ == "__main__":

      p = Pool(5)

      li = []

      for i in range(10):

        ret = p.apply(func=wahaha)     #同步的,不用

        print(ret)

    2 . 异步提交 , 不获取返回值

    import os,time

    from multiprocessing import Pool

    def inner():

      time.sleep(1)

      print(os.getpid())

    if __name__ == "__main__":

      p = Pool(5)  #进程池里的进程个数一般是CPU的个数,或者 + 1.

      for i in range(10):

        ret = p.apply_async(func=inner) #async   异步的

      p.close()  #关闭了进程池,让任务不能再继续提交了

      p.join()  #等待这个池中提交的任务都执行完,急等待所有子进程的代码都执行完,主进程才结束

    3 . 异步提交,获取返回值,等待所有任务都执行完毕之后再统一获取结果

    import os,time

    from multiprocessing import Pool

    def inner():

      time.sleep(1)

      print(os.getpid())

      return True

    if __name__ == "__main__":

      p = Pool(5)

      li = []

      for i in range(10):

        ret = p.apply_async(func=inner)

        li.append(ret)

      p.close()

      p.join()

      for ret in li:

        print(ret.get())

    4 . 异步提交,获取返回值,一个任务执行完毕之后就可以获取到一个结果(顺序是按照提交任务的顺序)

    import os,time

    from multiprocessing import Pool

    def inner():

      time.sleep(1)

      print(os.getpid())

      return True

    if __name__ == "__main__":

      p = Pool(5)

      li = []

      for i in range(10):

        ret = p.apply_async(func=inner)

        li.append(ret)

      for ret in li:

        print(ret.get())

    异步的 apply_async

    1 . 如果是异步得提交任务,那么任务提交之后进程池和主进程池也异步了,主进程不会自动等待进程池中的任务执行完毕

    2 . 如果需要主进程等待,需要 p.join 但是join的行为是依赖close的

    3 . 如果这个函数是有返回值的,也可以通过ret.get()来获取返回值,但是如果一边提交一遍获取返回值会让程序变成同步的;所以要想保留异步的效果,应该将返回对象保存在列表里,所有任务提交完成之后再来取结果,这种方式也可以去掉join,来完成主进程的阻塞等待池中的任务执行完毕.

    回调函数

    import os,time,random

    from multiprocessing import Pool

    def wrapper(num):

      time.sleep(random.random())

      print("pid :",os.getpid(),num)

      return num

    def back(arg):

      print("call_back:",os.getpid(),arg)

    if __name__ == "__main__":

      print("主进程",os.getpid())

      p = Pool(5)

      for i in range(10):

        ret = p.apply_async(func=wrapper,args=(i,),callback=back)

      p.close()

      p.join()

    回调函数 : 在主进程中执行

    在发起任务的时候,指定callback参数

    在每个进程执行完apply_async任务之后,返回值会直接作为参数传递给callback的函数,执行callback函数中的代码

    回调函数的用处 : 如果有两个任务,我的第二个任务在第一个任务执行完毕之后能够立即被主进程执行.

    进程 :

    是计算机中最小的资源分配单位

    在利用多个CPU执行的过程中,对多个程序的资源进行管理和隔离

    进程的弊端 :

    开启和关闭以及切换都会带来很大的时间开销

    过多的进程还会造成操作系统调度的压力

    线程 :

    线程是CPU调度的最小单位

    每个线程中至少有一个线程

    实际上执行代码的是线程

    线程属于进程 :

    线程不能独立存在,必须在一个进程里

    进程负责获取操作系统分配给自己的资源,线程负责执行代码

    从代码的角度上来看 :

    多进程 :

    开启和结束时间开销大 , 切换的效率低 , 内存隔离

    多线程 : 

    开启和结束时间开销非常小 , 切换效率高 , 内存不隔离

    Cpython解释器下的全局解释器锁 :

    在同一个进程中的多个线程在同一时刻只能有一个线程访问CPU

    多线程无法形成并行 ,使的一个进程中的多个线程不能充分利用多核.

    全局解释器锁,锁的是线程

    什么时候才会用到CPU?

    程序计算的时候

    IO阻塞, 是不会用到CPU的

    Jpython解释器就没有全局解释器锁

    pypy解释没有全局解释器锁

    一台机器中有4个CPU 最多能同时执行四个进程 , 进程里起线程

    threading模块初识

    import os,time

    from threading import Thread

    def func():

      time.sleep(1)

      print(123,os.getpid())

    print(123,os.getpid())

    for i in range(10):

      Thread(target=func).start()

    线程好还是进程好 ? == 什么时候用进程, 什么时候用线程?

    CPU的使用率 : 计算 --------多进程

    IO操作 : 网络/文件/数据库 -------- 多线程

    又有计算 , 又有IO操作--------------进程 + 线程

  • 相关阅读:
    【整理】Dword、LPSTR、LPWSTR、LPCSTR、LPCWSTR、LPTSTR、LPCTSTR
    C/C++中printf和C++中cout的输出格式
    左值的理解(给渴望学习的新手)
    c++ 指针精髓
    c++中的函数前面加个LRESULT是什么意思啊?
    pb调用vc写的动态链接库文件
    C++问题 & *用法
    vs2008下MFC内存泄露问题一点经验
    mysql5.6.41winx64安装
    开发是一件需要非常小心的工作
  • 原文地址:https://www.cnblogs.com/fengkun125/p/9391161.html
Copyright © 2020-2023  润新知