zoukankan      html  css  js  c++  java
  • 2019.9.12(day36)学习内容及笔记

    小结

    回顾及今日内容

    '''
    操作系统
    *****
    串行:一个进程完完整整执行完再执行下一个
    并发:看起来是同时运行  单核
    并行:真正的同时运行
    
    多道技术:
    空间复用:共用一个内存条,多个进程互相隔离,物理级别隔离
    时间复用:共用一个cpu
    
    
    *****
    程序:躺在硬盘上的文件
    进程:一个执行的程序,是一系列资源的总和
    如何在我们的进程里开子进程
    
    
    # 尽量减少阻塞状态可以提升我们的程序运行效率
    
    *****
    并发 = 保存状态 + 切换
    '''
    
    #*****
    # 开子进程  申请新的内存空间,把父进程的所有代码完整拷贝一份过去
    # 方式一
    from multiprocessing import Process
    
    def task(x):
        pass
    
    if __name__ == '__main__':
        p = Process(target=task, args=(5,))
        p.start()
    
    # 方式二(不常用)
    from multiprocessing import Process
    
    class Task(Process):
        def __init__(self, name):
            super().__init__()
            self.name = name
        def run(self):
            pass
    p = Task('Nick')
    p.start()
    
    # 验证内存空间彼此隔离
    
    #僵尸进程:父进程的子进程结束的时候父进程没有wait()情况下子进程会变成僵尸进程
    
    #####################今日内容############
    # 孤儿进程(无害的)* 就算父进程没有回收,__init__也会统一回收
    # 一个父进程退出,而它的一个或多个子进程还在运行,那么那些进程会变成孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集收集工作
    '''
    情况1  无害
    父进程等着子进程都死完,回收僵尸进程
    
    情况2  无害
    父进程死了, 子进程活着,都要被init进程接管并且回收
    
    情况3
    父进程一直不死,造成了大量僵尸进程。占用大量的pid号
    pid号是有限的
    解决方案:
    最直接的办法就是杀死父进程
    '''
    
    # join 的用法*****
    
    # Process的其它小用法*
    
    # 掌握pid 和 ppid的查看方式 *****
    
    # 守护进程 *****
    # 抢票小程序
    

    Process的join的用法

    from multiprocessing import Process
    import time
    # def foo():
    #     print('子进程 start')
    #     time.sleep(2)
    #     print('子进程 end')
    #
    # if __name__ == '__main__':
    #     p = Process(target=foo)
    #     p.start()
    #     #time.sleep(5)  现在不用time.sleep ,使用Process的join方法
    #     p.join() ## 阻塞住主进程在等待子进程结束,然后再往下执行(内部会调用wait())
    #     print('主进程')
    
    # from multiprocessing import Process
    # import time
    #
    # def foo(x):
    #     print('子进程 start')
    #     time.sleep(x)
    #     print('子进程 end')
    #
    # if __name__ == '__main__':
    #     p = Process(target=foo, args=(1,))
    #     p2 = Process(target=foo, args=(2,))
    #     p3 = Process(target=foo, args=(3,))
    #
    #     start = time.time()
    #     p.start()
    #     p2.start()
    #     p3.start()
    #
    #     p.join()
    #     p2.join()
    #     p3.join()
    #     # 总时长:按照最长的时间计算多一点
    #     end = time.time()
    #     print(end - start) #3.579204797744751
    #     print('主进程')
    
    from multiprocessing import Process
    import time
    
    def foo(x):
        print(f'进程{x} start')
        time.sleep(x)
        print(f'子进程{x} end')
    
    if __name__ == '__main__':
        p = Process(target=foo, args=(1,))
        p2 = Process(target=foo, args=(2,))
        p3 = Process(target=foo, args=(3,))
        start = time.time()
        # p.start()
        # p.join()
        # p2.start()
        # p2.join()
        # p3.start()
        # p3.join()
        foo(1)
        foo(2)
        foo(3)
        end = time.time()   # 直接调用函数时间:6.000343322753906
        print(end - start) #7.214412450790405 不如不开,直接使用串行调用函数反而块
        print('主进程')
    

    优化join

    from multiprocessing import Process
    import time
    
    def foo(x):
        print(f'进程{x} statr')
        time.sleep(x)
        print(f'进程{x} end')
    
    if __name__ == '__main__':
        start = time.time()
        p_list = []
        for i in range(1,4):
            p = Process(target=foo, args=(i,))
            p.start()
            p_list.append(p)
        print(p_list)
        for p in p_list:
            p.join()
        end = time.time()
        print(end - start) #3.584204912185669
        print('主进程')
    

    process的其它用法

    from multiprocessing import Process, current_process
    import time,os
    
    def task():
        print('子进程 start')
        print('在子进程中查看自己的pid',current_process().pid) # 在子进程中查看自己的pid
        print('在子进程中查看父进程的pid', os.getppid())
        time.sleep(100)
        print('子进程 end')
    
    if __name__ == '__main__':
        p = Process(target=task)
        p.start()
        print('在主进程查看子进程的pid', p.pid) # 一定要写在 start()之后
        print('主进程的pid', os.getpid())
        print('主进程的父进程Pid', os.getppid())
        print('主进程')
    
    '''
    记住这些就OK了  这个是要掌握的
    角度  站在当前进程对的角度
    os.getpid() #获取当前进程的pid
    os.getppid()  获取当前进程的父进程的pid
    子进程对象.pid  获取当前进程的子进程pid
    '''
    

    process的name和is_alive用法(了解)

    '''
    迭代:python中可以用for循环使用取值操作过程.
    可迭代对象:可以使用for循环遍历的对象,我们称之为可迭代对象.
    迭代器:提供数据和记录位置.
    生成器:如果函数中有yield我们称之为生成器
    '''
    # is_alive用法:判断进程是否还活着
    # from multiprocessing import Process
    # import time
    #
    # def foo():
    #     print('进程 start')
    #     time.sleep(2)
    #     print('进程 end')
    #
    # if __name__ == '__main__':
    #     p = Process(target=foo)
    #     p.start()
    #     print(p.is_alive())
    #     time.sleep(5)
    #     print(p.is_alive())
    #     print('主进程')
    
    # Process 的 name 用法
    from multiprocessing import Process, current_process
    import time
    
    def foo():
        print('进程 start')
        print(current_process().name)# current_process(现在进程的名字)
        time.sleep(2)
        print('进程 end')
    
    if __name__ == '__main__':
        p1 = Process(target=foo)
        p2 = Process(target=foo, name='rocky')
        p1.start()
        print(p1.is_alive()) #True
        p2.start()
        print(p2.is_alive()) #True
    
        time.sleep(5)
        print(p1.is_alive()) #False
        print(p2.is_alive()) #False
    
        print('主')
    

    process的terminate用法

    from multiprocessing import Process, current_process
    import time
    def foo():
        print('进程 start')
        time.sleep(20)
        print('进程 end')
    if __name__ == '__main__':
        p = Process(target=foo)
    
        p.start()
        p.terminate() # 给操作系统发送了一个请求,终止子进程
        print(p.is_alive()) # True
        p.join() #阻塞住主进程,等待子进程结束后才会往下运行,所以一旦往下运行了表示子进程已结束
        print(p.is_alive()) #False
        print('主进程')
    

    守护进程

    '''
    守护进程
    守护---》可以理解为伴随的意思
    本质也是一个子进程
    主进程的代码执行完毕后守护进程就直接结束。但是此时主进程可能没有结束
    '''
    
    from multiprocessing import Process
    import time
    
    def foo():
        print('守护进程 start')
        time.sleep(5)
        print('守护进程 end')
    
    if __name__ == '__main__':
        p = Process(target=foo)
        p.daemon = True # 表示把这个子进程定义为守护进程  daemon(守护进程)
        p.start()
        time.sleep(2)
        print('主进程')
    

    守护进程2

    '''
    守护进程
    守护--》伴随
    本质也是一个子进程
    主进程的代码执行完毕守护进程直接结束。
    '''
    
    from multiprocessing import Process
    import time
    
    def foo():
        print('守护进程 start')
        time.sleep(3)
        print('子进程 end')
    
    def task():
        print('子进程 start')
        time.sleep(5)
        print('子进程 end')
    
    if __name__ == '__main__':
        p = Process(target=foo)
        p1 = Process(target=task)
        p.daemon = True
        p.start()
        p1.start()
        time.sleep(1)
        print('主进程')
    

    抢票小程序

    db.txt = {"count": 1}
    
    from multiprocessing import Process
    import time
    import json
    import os
    
    def search():
        time.sleep(1) #模拟网络io
        with open('db.txt', 'rt', encoding='utf-8')as f:
            res = json.load(f)
            print(f'还剩{res["count"]}')
    
    def get():
        with open('db.txt', 'rt', encoding='utf-8')as f:
            res = json.load(f)
        time.sleep(1)  #模拟网络io
        if res['count'] > 0:
            res['count'] -= 1
            with open('db.txt', 'wt', encoding='utf-8')as f:
                json.dump(res,f)
                time.sleep(1.5) #模拟网络io
                print(f'进程{os.getpid()} 抢票成功')
        else:
            print('票已经售空啦!!')
    
    def task():
        search()
        get()
    
    if __name__ == '__main__':
        for i in range(15):
            p = Process(target=task)
            print(p)
            p.start()
            p.join()
    
    #为了保证数据的安全,要牺牲掉效率
    
    
    
  • 相关阅读:
    mybatis两种方式
    js绑定下拉框数据源
    修改 Idea 终端 Terminal 为 GitBash
    git stash使用
    解决百度网盘容量不符,没存进东西但容量变小的问题
    key_load_public: invalid format
    排序算法
    SpringBoot---自动配置原理
    mysql系列——Explain关键字(十)
    mysql系列——开启慢查询日志(十一)
  • 原文地址:https://www.cnblogs.com/chmily/p/11528234.html
Copyright © 2011-2022 走看看