zoukankan      html  css  js  c++  java
  • 并发与串行

    并发编程

    并发与串行

    程序默认执行方式是串行,即自上而下,当前任务执行完毕才能执行下一个任务,比较浪费时间

    问题举例:

    ​ 从硬盘读取大文件

    ​ 执行input

    学习并发的目的

    编写可执行多个任务的程序,提高效率

    串行和并发都是程序处理任务的方式

    如何实现并发

    多进程 (核心原理:多到技术)

    多线程

    协程

    进程和程序

    程序是 一堆代码放在一个文件中 通常后缀为exe 原本是存储在硬盘上的

    进程是 将代码从硬盘读取到内存然后执行 产生的

    进程是由程序产生的

    一个程序可以产生多个进程,例如qq多开 每一个进程都具备一个PID 进程变编号 且是唯一的

    多道技术

    空间复用

    时间复用 (切换+保存)

    ​ 切换的时机:遇到IO或执行时间超出阈值

    一个进程的三种操作

    阻塞

    非阻塞

    运行

    并发重要概念

    串行:自上而下顺序执行

    并发:同时执行多个任务,但本质是在不同进程间切换,由于速度非常快,所以感觉是同时运行

    并行:是真正的同时运行,但需要具备多核CPU,几核CPU就能并行几个任务,当任务数量超过核心数还是并发执行

    三个概念都是用于描述处理任务的方式

    阻塞:指程序遇到了IO操作,无法执行代码的 一种状态

    ​ input默认是一个阻塞操作

    非阻塞:指的是程序没有遇到IO操作的一种状态

    我们可以用一些手段非阻塞的操作变成非阻塞的操作,例如非阻塞的socket

    PID和PPID

    PID 是当前进程的编号

    PPID 是父进程的编号

    注意:当我们运行py文件时其实运行的是python解释器

    访问PID与PPID

    import os
    os.getpid()
    os.getppid()
    

    join的使用

    from multiprocessing import Process
    import time
    import random
    
    
    def task(n):
        time.sleep(random.randint(1, 3))
        print('-------->%s' % n)
    
    
    if __name__ == '__main__':
        ps = []
        for i in range(1, 4):
            p = Process(target=task, args=(i,))
            p.start()
            ps.append(p)
    
        for i in ps:
            i.join()
    
        print('-------->4')
    
    from multiprocessing import Process
    import time
    import random
    
    def task(n):
        time.sleep(random.randint(1,3))
        print('-------->%s' %n)
    
    if __name__ == '__main__':
        p1=Process(target=task,args=(1,))
        p2=Process(target=task,args=(2,))
        p3=Process(target=task,args=(3,))
    
        p1.start()
        p1.join()
        p2.start()
        p2.join()
        p3.start()
        p3.join()
        print('-------->4')
    

    进程对象常用属性

    if __name__ == '__main__':
        p = Process(target=task,name="老司机进程")
        p.start()
        # p.join()
        # print(p.name)
        # p.daemon #守护进程
        # p.join()
        # print(p.exitcode) # 获取进程的退出码   就是exit()函数中传入的值
        # print(p.is_alive())  # 查看进程是否存活
        # print("zi",p.pid) # 获取进程id
        # print(os.getpid())
        # p.terminate()  #终止进程  与strat 相同的是 不会立即终止,因为操作系统有很多事情要做  
        # print(p.is_alive())
    

    僵尸进程与孤儿进程

    孤儿进程 当父进程已经结束 而子进程还在运行 子进程就称为孤儿进程 尤其存在的必要性,没有不良影响

    僵尸进程 当一个进程已经结束了但是,它仍然还有一些数据存在 此时称之为僵尸进程

    在linux中,有这么一个机制,父进程无论什么时候都可以获取到子进程的的 一些数据

    子进程 任务执行完毕后,确实结束了但是仍然保留一些数据 目的是为了让父进程能够获取这些信息

    linux中 可以调用waitpid来是彻底清除子进程的残留信息

    python中 已经封装了处理僵尸进程的操作 ,无需关心

  • 相关阅读:
    软件工程第二次作业
    软件工程第一次作业
    软件工程最后一次作业
    软件工程第四次作业
    软件工程第三次作业
    软件工程第二次作业
    软件工程第一次作业
    《算法笔记》2.2小节——C/C++快速入门->顺序结构
    大数阶乘
    printf("%f ",5)的输出结果为什么是0.000000
  • 原文地址:https://www.cnblogs.com/einsam/p/11123202.html
Copyright © 2011-2022 走看看