• fork和multiprocessing


    多任务理解

     

    单核cpu完成多个cpu的切换

    时间片轮转

    优先级调度

    并发看上去一起执行

    并行一起执行

    调度算法

    什么样的情况下用什么样的规则让谁去执行.

    一般情况下电脑都是并发的

    进程的创建-fork

    进程VS程序

    编写完毕的代码,在没有运行的时候,称为程序

    正在运行的代码,称为进程

    进程,除了包含代码以外,还有需要运行的环境,所以和程序是有区别的

    fork()

    fork创建一个进程,ret大于0是父进程,不确定返回几,ret等于0是子进程

    在linux系统下(centos)才能执行,windows提示没有fork方法

    import os
    import time
    ret = os.fork()
    if  ret == 0:
        while True:
            print('--1--')
            time.sleep(1)
    else:
        while True:
            print('--2--')
            time.sleep(1)

    一般操作系统能运行65535个进程,pid就像人的身份证,不可能相同

    getpid获取当前进程的值

    getppid获取当前进程父进程的值

    父进程中fork的返回值,就是刚刚创建的子进程的ID

    fork产生一个子进程,几乎同时打印父进程子进程1,然后父进程睡三秒,打印over,子进程1在父进程睡三秒的同时睡五秒,所以过了两秒后打印子进程2,然后打印over

    import os 
    import time
    
    ret =os.fork()
    
    if ret==0:
        print('---子进程1---')
        time.sleep(5)
        print('---子进程2---')
    else:
        print('---父进程---')
        time.sleep(3)

    print('---over---')

    全局变量在多个进程数据不共享

    进程和进程之间数据不会共享

    import os 
    import time 
    
    g_num=100
    
    ret = os.fork()
    if ret == 0:
        print('---process-1---')
        g_num+=1
        print('---process-1 g_num=%d---'%g_num)
    else:
        time.sleep(1)
        print('---process-2---')
        print('---process-2 g_num=%d---'%g_num)

    网络的目的在于进程间的通信

    多次fork

    共四个进程

    import os 
    import time
    
    ret = os.fork()
    if ret == 0:
      #子进程
    print('---1---') else:
      #父进程
    print('---2---') #父子进程 ret = os.fork()#到这一步时,上面父进程和fork出来的子进程又都分别fork了一份进程 if ret ==0:
      #父进程的第二个子进程
      #子进程的儿子
    print('---11---') else:
      #父进程
      #子进程
    print('---22---')

    上段代码的变形,共有三个进程

    import os 
    import time
    
    ret = os.fork()
    if ret == 0:
      #子进程
    print('---1---') else:
      #父进程
    print('---2---') ret = os.fork() if ret ==0:
         #父进程的第二个子进程
    print('---11---') else:
         #父进程
    print('---22---')

    如果在某个进程下fork,那么就只能多一个进程,如果在父子进程都能执行的地方fork,它们就会各生一个儿子,就多了两个进程了

    几个fork就能创建2的几次方个进程

    import os
    #fork炸弹,贼吊,不信试试
    while True:
        os.fork()

    fork不能跨平台,我们用multiprocessing模块,它能跨平台

    from multiprocessing import Process
    import time
    
    
    def test():
        while True:
            print('---test---')
            time.sleep(1)
    
    
    p = Process(target=test)
    p.start()  # 让这个子进程开始执行test函数里的代码,函数里的代码执行完后,进程也就结束了

    #主进程 while True: print('---main---') time.sleep(1)

    对上面的代码做了一些改进,只有等到子进程执行完,主进程才会结束

    from multiprocessing import Process
    import time
    
    
    def test():
        for i in range(5):
            print('---test---')
            time.sleep(1)
    
    
    p = Process(target=test)
    p.start()  # 让这个进程开始执行test函数里的代码,函数里的代码执行完后,进程也就结束了

    join

    from multiprocessing import Process
    import time
    import random
    
    
    def test():
        for i in range(random.randint(1,5)):
            print('---%d---'%i)
            time.sleep(1)
    
    
    p = Process(target=test)
    p.start()  # 让这个进程开始执行test函数里的代码,函数里的代码执行完后,进程也就结束了
    p.join(2)#阻塞,等多少秒
    print('---main---')

    process子类

    创建新的进程还能够使用类的方式,可以自定义一个类,继承process类,每次实例化这个类的时候,就等于实例化这个进程对象

    进程池,缓冲数据用

    没有因为进程数少于任务数而阻塞,创建进程池是3表示最多3个同时干活,不用销毁进程节省了时间

    from multiprocessing import Pool
    import os
    import time
    
    def worker(num):
        for i in range(5):
            print('---pid=%d---num=%d' % (os.getpid(), num))
            time.sleep(1)
    
    #3表示进程池中最多有3个进程一起执行
    pool = Pool(3)
    for i in range(10):
        print('---%d---' % i)
        #向进程池中添加任务
        #注意:如果添加的任务数量超过了进程池中进程的个数的话,那么不会导致添加不进去
        # 添加到进程池中的任务,如果还没有被执行的话,那么此时,它们会等待进程池中的进程完成一个任务之后,
        # 会自动去掉用刚刚的那个进程,完成当前的新任务
        pool.apply_async(worker, (i,))
    
    pool.close()#关闭进程池,相当于不能再添加新任务了
    pool.join()#主进程创建/添加任务后,主进程默认不会等待进程池中的任务执行完后才结束,
    # 而是当主进程的任务做完之后,立马结束,如果这个地方没有join,会导致进程池中的任务不会执行
  • 相关阅读:
    2021牛客OI赛前集训营提高组(第二场)
    记一个区间问题的 trick
    1076. Forwards on Weibo (30)(图的遍历bfs)
    1034 Head of a Gang (30 分)(图的遍历dfs)
    1098 Insertion or Heap Sort (25 分)(堆排序)【回顾】
    1072. Gas Station (30)(Dijkstra)
    1013. Battle Over Cities (25)(图的遍历,统计强连通分量的个数,dfs)
    1018. Public Bike Management (30)(Dijkstra + DFS)
    1021. Deepest Root (25)(图的遍历,dfs,连通分量的个数)
    1087. All Roads Lead to Rome (30)(Dijkstra + DFS)
  • 原文地址:https://www.cnblogs.com/z-x-y/p/10117317.html
Copyright © 2020-2023  润新知