并发进程

Posted 0627zhou

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了并发进程相关的知识,希望对你有一定的参考价值。

1.计算机硬件和操作系统

  1. 计算机硬件组成:

 

    • 主板:固化(寄存器,是直接和cpu进行交互的一个硬件)
    • cpu:中央处理器,能够进行数学运算和一些逻辑运算,并且控制所有硬件协调工作
    • 存储:硬盘和内存
    • 输入设备:键盘,鼠标,话筒
    • 输出设备:显示器,音响,打印机

 

  • 早期的计算机是以计算为核心的
  • 现在的计算机是以存储为核心的

  2.计算机操作系统:

    • 操作系统是一个软件,是一个能直接操纵硬件的一个软件
    • 它的目的是让用户用起来更加的轻松,高可用,低耦合;
    • 几个代表性系统:dos  windows unix

操作系统的作用:

  • 封装所有硬件接口,让各种用户使用电脑更加轻松;
  • 是对计算机内所有的资源进行合理的调度和分配; 

2.进程的理论

  1. 几个后缀文件:

 

    • .sh  shell脚本文件
    • .out linux系统中的可执行文件
    • .bat 批处理脚本文件
    • .lib 库文件
    • .dll 库
    • .exe 可执行文件

  2.进程:

    • 是指正在执行的程序;
    • 是程序执行过程中的一次指令
    • 也可以叫做程序的一次执行过程
    • 进程是一个动态的概念

  3.进程三大部分组成:代码段,数据段,PCB:进程管理调度

  4.进程的三大基本状态

    • 就绪状态:已经获得运行需要的所有资源,除了cpu
    • 执行状态:已经获得了所有资源包括cpu,处于正在执行
    • 阻塞状态:因为各种原因,进程放弃了cpu,导致进程无法继续执行;此时进程处于内存中,继续等待获取cpu
    • 因为各种原因,进程放弃了cpu,导致进程无法继续执行,此时进程被踢出内存;

3.关于进程的一些名词

  • 并行:是指两者同时执行,一定是多个车道,在同一时间点
  • 并发:是指在资源有限的情况下,两者轮流使用资源,只有一条赛道
  • 同步:就是一个任务的完成需要依赖另外一个任务时,只有等待被依赖的任务完成后,才能继续进行,是可靠的任务序列,要么成功都成功,失败都失败,两个任务的状态可以保持一致;
  • 异步:不需要等待被依赖的任务完成,只是通知被依赖的任务要完成什么工作,依赖的任务也会立即执行,至于被依赖的任务最终是否真正完成,依赖它的任务无法确定,所以它是不可靠序列;
  • 技术分享图片
    同步:比如你去商店买书,你问老板有没有<古龙小说集>,老板说我给你查查,然后你就一直等,有可能等一天,有可能等一个小时,必须等到一个结果,你才去进行下一步;
    
    异步:还是你去买书,你问老板有没有,老板说,你先回去吧,我帮你查查,有了电话通知你,你得到一个结果,可是这个结果并不是真实的结果,只是一个反馈结果而已;
    
    阻塞:还是买书,你问老板有没有,老板说我帮你查查,然后你会一直在等,等到天荒地老,什么也不干,等一个结果;
    
    非阻塞:还是买书,你问老板有没有,老板说我帮你查查,你说老板你先查着,我先玩一会,然后你一会在过来看看;
    例子
  • 阻塞与非阻塞:阻塞和非阻塞这两个概念与程序(线程)等待消息通知(无所谓同步或者异步)时的状态有关。也就是说阻塞与非阻塞主要是程序(线程)等待消息通知时的状态角度来说的
  • 技术分享图片
    同步阻塞形式
      效率最低。拿上面的例子来说,就是你专心排队,什么别的事都不做。
    
    异步阻塞形式
      如果在银行等待办理业务的人采用的是异步的方式去等待消息被触发(通知),也就是领了一张小纸条,假如在这段时间里他不能离开银行做其它的事情,那么很显然,这个人被阻塞在了这个等待的操作上面;
    
      异步操作是可以被阻塞住的,只不过它不是在处理消息时阻塞,而是在等待消息通知时被阻塞。
    
    同步非阻塞形式
      实际上是效率低下的。
    
      想象一下你一边打着电话一边还需要抬头看到底队伍排到你了没有(两个操作不能同时执行,因为是同步),如果把打电话和观察排队的位置看成是程序的两个操作的话,这个程序需要在这两种不同的行为之间来回的切换,效率可想而知是低下的。
    
    异步非阻塞形式
      效率更高,
    
      因为打电话是你(等待者)的事情,而通知你则是柜台(消息触发机制)的事情,程序没有在两种不同的操作中来回切换。
    
      比如说,这个人突然发觉自己烟瘾犯了,需要出去抽根烟,于是他告诉大堂经理说,排到我这个号码的时候麻烦到外面通知我一下,那么他就没有被阻塞在这个等待的操作上面,自然这个就是异步+非阻塞的方式了。
    四个名词

4. multiprocessing.Process模块

1.进程两种开启方式:实例化一个进程的对象:

def func():
    print(子进程1的爸爸是%s,我是%s % (os.getppid(),os.getpid()))
def func2():
    print(子进程2的爸爸是%s,我是%s % (os.getppid(), os.getpid()))

if __name__ == __main__:
    li = [func, func2]
    for i in li:
        p = Process(target=i)
        p.start()
    print(主进程的爸爸是%s,我自己是%s % (os.getppid(),os.getpid()))

#主进程的爸爸是1116,我自己是12760
子进程1的爸爸是12760,我是848
子进程2的爸爸是12760,我是11588

2.通过继承

class Myprocess(Process):
    def __init__(self,name):
        super(Myprocess, self).__init__()
        self.name = name
    def run(self):
        print(这是以继承类的方式开启的子进程%s,他的名字是%s %(os.getppid(),self.name))

if __name__ == __main__:
    p = Myprocess(alex)
    p.start()
    print(这里是主进程%s % os.getpid())

3.进程的常用方法

  1. start() 开启一个子进程
  2. join() 异步变同步(就是让父进程停留在join这句话,等待子进程执行结束)
  3. is_alive()判断进程是否还活着
  4. terminate()杀死进程

每个方法的代码演示:

 

技术分享图片
from multiprocessing import Process
import time

def func():
    for i in range(500):
        time.sleep(0.01)
        print(儿子在这里)

if __name__ == __main__:
    p = Process(target=func)
    p.start()
    p.join()# 是让主进程等待子进程执行完。  现象:主进程执行到这句话,主进程阻塞住,等待子进程执行
    for i in range(100):
        time.sleep(0.01)
        print(爸爸在这里)

# 开启一个正常的子进程,父进程会等待子进程结束后,父进程也就是程序才结束
# p.join()# 是让主进程等待子进程执行完。  现象:主进程执行到这句话,主进程阻塞住,等待子进程执行
# 如何把父进程和子进程之间的关系变为同步或者异步?
# 父进程执行join,就会变成同步,不执行join,父进程和子进程就是异步的关系
# join必须放在start()后边
join和start

 

技术分享图片
from multiprocessing import Process
import time


def func():
    time.sleep(1)
    print(123)


if __name__ == __main__:
    p = Process(target=func,)
    p.start()
    p.terminate()# 杀死p进程,让解释器告诉操作系统,请杀掉p进程。
    print(子进程是否还活着?, p.is_alive())
    time.sleep(0.002)
    print(子进程是否还活着?, p.is_alive())
    # 返回一个bool值,如果返回True,代表进程还活着,如果返回False,代表子进程死了

# p.is_alive() 判断p进程是否还活着
# p.terminate() 杀死p进程
is_alive和terminate

4.进程的常用属性

  • p.name = 给p进程的一个名字
  • p.pid = 返回p进程的pid
  • p.daemon = True 将p进程设置为守护进程(True为守护进程,False为普通进程)
    • 守护进程的两个特点:
    • 守护进程会随着父进程的结束而结束
    • 守护进程不能再创建子进程(不能有孩子)

 

技术分享图片
from multiprocessing import Process
import time
def func():
    for i in range(10):
        time.sleep(1)
        print(time.strftime("%H:%M:%S"))
if __name__ == __main__:
    #设置为守护进程后,会根据主进程想要的效果停止的子进程
    p = Process(target=func)
    p.daemon = True
    p.start()
    time.sleep(5)
    print(计时结束!)
#输出结果
20:15:49
20:15:50
20:15:51
20:15:52
20:15:53
20:15:54
计时结束!
守护进程的作用
技术分享图片
from multiprocessing import Process
import time
import os

def func():
    print(这里是儿子,儿子的pid是%s%(os.getpid()))

if __name__ == __main__:
    p = Process(target=func)
    p.start()
    p.name = alex
    print(儿子的名字是%s%p.name)
    print(儿子的pid是%s%p.pid)
    print(儿子是不是守护进程?,p.daemon)
其他属性

 

以上是关于并发进程的主要内容,如果未能解决你的问题,请参考以下文章

golang goroutine例子[golang并发代码片段]

进程互斥与同步

在 Python 多处理进程中运行较慢的 OpenCV 代码片段

如何从设置中获取数据并发送到此片段

Swift新async/await并发中利用Task防止指定代码片段执行的数据竞争(Data Race)问题

Swift新async/await并发中利用Task防止指定代码片段执行的数据竞争(Data Race)问题