zoukankan      html  css  js  c++  java
  • 并发编程

    并发编程

    • 什么是并发编程

      并发指的是多个任务同时被执行,并发编程指的是编写支持多任务的应用程序

    并发编程中重要的概念*******

    1串行:自上而下顺序执行

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

    3并行:是真正的同时进行,必须具备的是多核CPU,有几个核心就能并行几个任务,当任务数量超过核心数,任务进行并发

    遇到的状态:

    阻塞和非阻塞可以用来描述执行任务的方式

    1阻塞:程序遇到了IO操作,无法继续执行代码一种

    • input()默认是一个阻塞操作

    2非阻塞:程序没有遇到IO操作的一种

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

    一个进程的三种状态:1阻塞,2运行,3就绪

    并发和串行

    目前程序存在的问题

    默认执行方式是串行,所谓串行,即程序自上而下运行,一行行代码执行,必须把当前任务执行完才进行下面的任务,不管花多长时间

    e.g.

    • 在tcp服务器中,如果正在进行通讯循环无法处理其他客户的要求
    • 在硬盘中读取大文件
    • 执行input

    学习并发的目的

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

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

    多道技术是

    实现原理:---------------------有了多道技术,计算机就可以同时并发处理多个任务

    1,空间复用:

    ​ 同一时间,加载多个任务到内存中,多个进程之间内存区域需要相互隔离,这个隔离是物理层面的隔离,目的是保证数据的安全

    2,时间的复用:

    ​ 操作系统会在多个进程之间按做切换执行,切换任务的两个情况

    • 1当一个进程遇到了IO操作,会自动切换
    • 2当一个任务执行时间超过阈值会强制i切换

    在切换前必须保存状态,以便恢复执行----频繁切换是需要消耗资源的

    当所有任务都没有io操作时,切换执行效率反而降低,为了保证并发执行,必须牺牲效率

    进程

    什么是进程

    1,进程指的是正在运行的程序,是一系列过程的统称,也是操作系统在调度和进行资源分配的基本单位

    2,进程怎么来的:当程序从硬盘读入内存,进程就产生了

    3,多进程的概念:多个程序同一时间被装入内存并且执行(一个程序可以产生多个进程,比如说运行多个qq程序)

    进程是实现并发的一种方式-------涉及到操作系统,因为这个概念来自于操作系统,没有操作系统就没有进程

    • 多进程实现原理就是操作系统调度进程的原理

    进程的创建和销毁

    创建:

    • 用户的交互式请求,鼠标双击
    • 由一个正在运行的程序,调用了开启进程的接口,例如 subprosess
    • 一个批作业的开始
    • 系统的初始化

    销毁:

    • 任务完成,自愿退出
    • 强制退出,taskkill kill(非自愿)
    • 程序遇到了异常
    • 严重的的错误,访问了不该访问的内存

    PID和PPIFD

    PID是当前进程的编号

    PPID是父进程的编号

    在运行py文件时其实是运行的python解释器

    访问PID  PPID
    import os
    os.getpid()
    os.getppid()
    
    

    python如何使用多进程

    创建子进程的方式

    1导入multiprocessing 中的Process类 实例化这个类,指定要执行的任务target

    import os
    from multiprocessing import Process
    """process 就表示进程"""
    def task():
        print("this is sub process")
        print("sub process id %s"% os.getpid())
    if __name__=='__main__'
    	"开启进程的代码必须是放在__main__判断下面"
        #实例化一个进程对象,并制定他要做的事情,函数来指定
        p=Process(target =task)
        p.start()     #给操作系统发送信息,让其开启进程
        print("this is parent process")
        print('parent process is %s'% os.getpid())
        print('over')
    

    widows 回到如父进程的代码,从头执行一遍,来获取需要处理的任务

    所以在编写代码时如果是windows一定要开启进程的代码放在main判断中

    linux可以不放

    2导入multiprocessing中的Process类,覆盖run的方法,将要执行的任务放在run中,开启进程时会自动执行该函数

    from multiprocessing import Process
    import os
    class Downloader(Process)
    	#def__init__(self,url,size,name):
        #	super().__init__()
        #	self.url =url
        #	self.size =size
        #	self.name=name
        
        def run(self):
            print(os.getpid())
            pass
        
    if __name__=='__main__'
    	m=Downloader()
        m.start()
        print("parent over",os.getpid())
        
    	
    

    3进程之间内存相互隔离

    from multiprocessing import Process
    import os,time
    a=257
    
    def task():
        global a
        #print("2",a,id(a))
        a=200
        
    if __name__=='__main__'
    	p=Process(target=task)
        p.start()  #像操作系统发送指令
        
        time.sleep(4)
        print(a)
    

    4join函数

    from multiprocessing import Process
    import time
    def task1(name):
        for i in range(1000):
            print("%s run"% name)
    def task2(name):
        for i in range(100):
            print("%s run"% name)
            
    if __name__=='__main__':   #args 是给子进程传参的参数,必须是元组
        p1=Process(target=task1,arg=("p1",))
        p1.start()  #向操作系统发送指令
        #p1.join()  #让主进程 等待子进程执行完毕再急促执行
        
        p2 =Process(target=task2,args("p2",0))
        p2.start()
        
        
        p2.join()
        p1.join()
        
        #需要达到的效果是 必须保证两个子进程是并发执行的,并且over一定是在所有执行完毕后才执行的
        print('over')
        
        
    

    案例:join的使用

    #join使用
    from multiprocessing import Process
    import time
    def task1(name):
        for i in range(10):
            print("% run "% name)
            
    if __name__=='__main__':  #args 是给子进程传递额参数,必须是元组
        ps =[]
        for i  in range(10):
            p=Process(target=task1,arg=(i,))
            p.start()
            ps.append(p)
            
        #换个join下
        for i in ps:
            i.join()
            
        print('over')
        
    

    进程对象的常用属性:

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

    僵尸进程和孤儿进程

    孤儿进程:当父进程已经结束了,而子进程还在运行,子进程就变成了孤儿进程,尤其是存在的重要性,没有不良影响

    僵尸进程:当一个进程结束了,它任然还有一些数据存在,此时称之为

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

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

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

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

  • 相关阅读:
    CSU software 新手练习1 解题报告
    HDU 4067 Random Maze
    HDU 1853 Cyclic Tour
    Notepad++搭配MinGW编译运行C,C++程序
    ACM POJ3299-Humidex
    开始正常的做题了=。=
    写在杭电热身赛2之后
    大二了~
    Vim 学习笔记之cvim hot key
    The 10th Zhejiang Provincial Collegiate Programming Contest
  • 原文地址:https://www.cnblogs.com/zhuyuanying123--/p/11122701.html
Copyright © 2011-2022 走看看