我是靠谱客的博主 等待龙猫,最近开发中收集的这篇文章主要介绍python_day34_进程 并发进程 孤儿进程 僵尸进程,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述


进程  多进程   孤儿,僵尸进程 

进程就是正在运行的程序,程序就是程序员编写的一段代码,当这些代码被系统加载到内存中被cpu执行时,进程就产生了. 

单个程序可以产生多个进程    利用tasklist可以来层查看   例如打开多个qq

PID 和PPID

PIP

在一个操作系统中通常都会运行多个应用程序,也就是多个进程,那么如何来区分进程呢?

系统会给每一个进程分配一个进程编号即PID,如同人需要一个身份证号来区分。

验证:

tasklist 用于查看所有的进程信息

taskkill  /f /pid  pid 该命令可以用于结束指定进程

在Python中  可以利用  os模块查看进程名称
import  os
print(os.getpid())

 

PPIP(父进程的进程标识) 

当a进程开启了b进程   那么a进程就是b进程的父进程   b就是a进程的子进程

可以通过os模块可以查询父进程的pip

# 在python中可以使用os模块来获取ppid
import os
print("self",os.getpid()) # 当前进程自己的pid
print("parent",os.getppid()) # 当前进程的父进程的pid

 

进程的三种状态   (重点)

 

python中实现多进程

在一个应用程序中可能会有多个任务需要并发执行,但是对于操作系统而言,一个进程就是一个任务,CPU会从上往下依次执行代码,当代码中遇到IO操作时,操作系统就会剥夺CPU执行权给其他应用程序,这样对于当前应用程序而言,效率就降低了,如何使得程序既能完成任务又不降低效率呢?答案就是让把当前程序中的耗时操作交給子进程来完成,如此当前应用程序可以继续执行其他任务!

Python中实现子进程的两种方式  (重点)

方式一  实例化Process类
from multiprocessing import Process
import os

def task(name):  # 因为父进程中  关键字给了属性  则需要有一个参数来接收  name可以用name接收一下
    print("%s进程run!" %name)
    print("%s进程over!" % name)


if __name__ == '__main__':
    p = Process(target=task,args=('Tom',))
    # 实例化一个Process类对象
    # 可以为子进程起个名字  比如tom  但是注意 必须是元祖
    print('father进程:%s' % os.getpid()) # 打印下父进程的pip看看
    p.start()  #  需要交给系统去执行  start去执行
    print('父进程RUN!')
    
#  这时先运行父进程代码  然后再去执行子进程代码

"""
windows  和  linux 开启进程的方式不同 
首先相同之处都是 需要将数据copy一份给子进程   这样子进程才知道要干什么  
linux 会将父进程的所有数据 完全copy    
windows  会copy 一部分数据   同时会导入py文件来执行   这样一来递归开进程    
linux 拿到父进程知道代码位置 继续执行   
建议都加上判断  可以保证两个平台都能用  

记住:
开启进程的代码 都把它放到  if __name__ == "__main__": 中即可


"""

 

 

方案二   继承Process类        自定义run类来实现自定义的功能

import os
from multiprocessing import  Process
class MyProcess(Process):  #  继承Process类
    def __init__(self,name):
        super().__init__() # 这时需要super 因为要覆盖run方法
        self.name = name
    # 继承Procee覆盖run方法将要执行任务发到run中
    def run(self):
        print(self.name)
        print("子进程 %s running!" % os.getpid())
        print("子进程 %s over!" % os.getpid())

if __name__ == '__main__':
    # 创建时 不用再指定target参数了
    p = MyProcess("rose")
    p.start()
    print("父进程over!")
    
    .第二种方式中,必须将要执行的代码放到run方法中,子进程只会执行run方法其他的一概不管

 

 

进程间内存是相互隔离的

进程  多进程   孤儿,僵尸进程  
进程就是正在运行的程序,程序就是程序员编写的一段代码,当这些代码被系统加载到内存中被cpu执行时,进程就产生了.  

单个程序可以产生多个进程    利用tasklist可以来层查看   例如打开多个qq

PID 和PPID
PIP
在一个操作系统中通常都会运行多个应用程序,也就是多个进程,那么如何来区分进程呢?

系统会给每一个进程分配一个进程编号即PID,如同人需要一个身份证号来区分。

验证:

tasklist 用于查看所有的进程信息 

taskkill  /f /pid  pid 该命令可以用于结束指定进程


在Python中  可以利用  os模块查看进程名称
import  os 
print(os.getpid())
PPIP(父进程的进程标识)  
当a进程开启了b进程   那么a进程就是b进程的父进程   b就是a进程的子进程

可以通过os模块可以查询父进程的pip


# 在python中可以使用os模块来获取ppid
import os
print("self",os.getpid()) # 当前进程自己的pid
print("parent",os.getppid()) # 当前进程的父进程的pid
# 在python中可以使用os模块来获取ppid
import os
print("self",os.getpid()) # 当前进程自己的pid
print("parent",os.getppid()) # 当前进程的父进程的pid
进程的三种状态   (重点)


多道技术会在进程执行时间过长或遇到IO时会自动切换其他进程,意味着IO操作与进程被剥夺CPU执行权时都会造成进程无法继续执行

python中实现多进程
在一个应用程序中可能会有多个任务需要并发执行,但是对于操作系统而言,一个进程就是一个任务,CPU会从上往下依次执行代码,当代码中遇到IO操作时,操作系统就会剥夺CPU执行权给其他应用程序,这样对于当前应用程序而言,效率就降低了,如何使得程序既能完成任务又不降低效率呢?答案就是让把当前程序中的耗时操作交給子进程来完成,如此当前应用程序可以继续执行其他任务!

Python中实现子进程的两种方式  (重点)
方式一  实例化Process类 

from multiprocessing import Process
import os

def task(name):  # 因为父进程中  关键字给了属性  则需要有一个参数来接收  name可以用name接收一下
    print("%s进程run!" %name)
    print("%s进程over!" % name)


if __name__ == '__main__':
    p = Process(target=task,args=('Tom',))
    # 实例化一个Process类对象
    # 可以为子进程起个名字  比如tom  但是注意 必须是元祖
    print('father进程:%s' % os.getpid()) # 打印下父进程的pip看看
    p.start()  #  需要交给系统去执行  start去执行
    print('父进程RUN!')
    
#  这时先运行父进程代码  然后再去执行子进程代码

"""
windows  和  linux 开启进程的方式不同 
首先相同之处都是 需要将数据copy一份给子进程   这样子进程才知道要干什么  
linux 会将父进程的所有数据 完全copy    
windows  会copy 一部分数据   同时会导入py文件来执行   这样一来递归开进程    
linux 拿到父进程知道代码位置 继续执行   
建议都加上判断  可以保证两个平台都能用  

记住:
开启进程的代码 都把它放到  if __name__ == "__main__": 中即可


"""
from multiprocessing import Process
import os
​
def task(name):  # 因为父进程中  关键字给了属性  则需要有一个参数来接收  name可以用name接收一下
    print("%s进程run!" %name)
    print("%s进程over!" % name)
​
​
if __name__ == '__main__':
    p = Process(target=task,args=('Tom',))
    # 实例化一个Process类对象
    # 可以为子进程起个名字  比如tom  但是注意 必须是元祖
    print('father进程:%s' % os.getpid()) # 打印下父进程的pip看看
    p.start()  #  需要交给系统去执行  start去执行
    print('父进程RUN!')
    
#  这时先运行父进程代码  然后再去执行子进程代码
"""
windows  和  linux 开启进程的方式不同 
首先相同之处都是 需要将数据copy一份给子进程   这样子进程才知道要干什么  
linux 会将父进程的所有数据 完全copy    
windows  会copy 一部分数据   同时会导入py文件来执行   这样一来递归开进程    
linux 拿到父进程知道代码位置 继续执行   
建议都加上判断  可以保证两个平台都能用  
​
记住:
开启进程的代码 都把它放到  if __name__ == "__main__": 中即可
​
​
"""
方案二   继承Process类        自定义run类来实现自定义的功能



import os
from multiprocessing import  Process
class MyProcess(Process):  #  继承Process类
    def __init__(self,name):
        super().__init__() # 这时需要super 因为要覆盖run方法
        self.name = name
    # 继承Procee覆盖run方法将要执行任务发到run中
    def run(self):
        print(self.name)
        print("子进程 %s running!" % os.getpid())
        print("子进程 %s over!" % os.getpid())

if __name__ == '__main__':
    # 创建时 不用再指定target参数了
    p = MyProcess("rose")
    p.start()
    print("父进程over!")
    
    .第二种方式中,必须将要执行的代码放到run方法中,子进程只会执行run方法其他的一概不管


​
import os
from multiprocessing import  Process
class MyProcess(Process):  #  继承Process类
    def __init__(self,name):
        super().__init__() # 这时需要super 因为要覆盖run方法
        self.name = name
    # 继承Procee覆盖run方法将要执行任务发到run中
    def run(self):
        print(self.name)
        print("子进程 %s running!" % os.getpid())
        print("子进程 %s over!" % os.getpid())
​
if __name__ == '__main__':
    # 创建时 不用再指定target参数了
    p = MyProcess("rose")
    p.start()
    print("父进程over!")
    
    .第二种方式中,必须将要执行的代码放到run方法中,子进程只会执行run方法其他的一概不管
​
​
​
​
进程间内存是相互隔离的 

from multiprocessing import Process
import time
name = "青椒"
def task():
    global name
    name = "rose"
    print("改完了!")
    print("子进程的%s" % name)
​
​
if __name__ == '__main__':
    p = Process(target=task)
    p.start()
    time.sleep(2)
    print(name)  # 打印是青椒  并不是rose   因为进程间内存是互相隔开的
    
 结果 :   
改完了!
子进程的rose
青椒    

 

进程中的join 的用法  (重点)

上述的都是先完成父类进程再去完成子类的进程    但是有时父类的进程不需要自己完成再去完成子类 的 它需要子类完成后再来执行的进程  那么join就派上用上了

join在进程中的用法就是   让子进程运行完毕之后再去运行父进程

#  join就是让子进程运行完了 再去执行父进程

from multiprocessing import Process
name = 'rose'
def task():
    global name
    name = 'tom'
    print(name)
    print('子进程在run!')


if __name__ == '__main__':
    p = Process(target=task)
    p.start()
    p.join()
    print(name)
    print('父进程run!')

# tom
# 子进程在run!
# rose
# 父进程run!

 

案例二
from multiprocessing import Process
import time

def task(i):
    # print(" %s 买烟去了" % i)
    time.sleep(i)
    print("%s 买完了!" % i)

if __name__ == '__main__':
    strat_time = time.time()
    p1 = Process(target=task,args=(1,))
    p2 = Process(target=task,args=(2,))
    p3 = Process(target=task,args=(3,))

    p1.start()
    p2.start()
    p3.start()

    p3.join() #3
    p2.join()
    p1.join()


    end_time = time.time()
    print(end_time - strat_time)  # 总共三秒多
    print("over!")

 

 

Process的其他用法

from multiprocessing import  Process
import time,os
def task():
    print("121121")
    # time.sleep(10)
    # print("over")
    # print(os.getppid())
    exit(1000)

if __name__ == '__main__':
    p = Process(target=task,name="rose")
    p.start() # 懒加载优化机制  如果没有调用start 那么该对象将不会被创建
    time.sleep(1)
    # p.join() # 等待子进程结束
    # p.terminate()  # 终止进程
    # print(p.name)  # 进程的名称
    # print(p.is_alive()) #是否存活
    # p.terminate() # 与start一样 都是给操作系统发送指令 所以会有延迟
    # print(p.is_alive())
    # print(p.pid)
    # print(p.exitcode) # 获取退出码

 

孤儿进程   僵尸进程  (了解)

孤儿进程:指的是开通子进程之后,父进程结束了,而子进程还没运行结束,那这个子进程就成为了孤儿进程,但是这个进程还有有存在的必要的,它没有父进程,接管方就变成了操作系统.

例子;  比如qq打开浏览器   qq关闭了  浏览器还在运行 

 

僵尸进程:僵尸进程指的是,当子进程比父进程先结束,而父进程又没有回收子进程,释放子进程占用的资源,此时子进程将成为一个僵尸进程。如果父进程先退出 ,子进程被操作系统接管,子进程退出后操作系统会回收其占用的相关资源!

 

僵尸进程的危害:

由于子进程的结束和父进程的运行是一个异步过程,即父进程永远无法预测子进程 到底什么时候结束. 那么会不会因为父进程太忙来不及wait子进程,或者说不知道 子进程什么时候结束,而丢失子进程结束时的状态信息呢? 不会。因为UNⅨ提供了一种机制可以保证只要父进程想知道子进程结束时的状态信息, 就必然可以得到。这种机制就是: 在每个进程退出的时候,内核释放该进程所有的资源,包括打开的文件,占用的内存等。但是仍然为其保留一定的信息(包括进程号the process ID,退出状态the termination status of the process,运行时间the amount of CPU time taken by the process等)。直到父进程通过wait / waitpid来取时才释放. 但这样就导致了问题,如果进程不调用wait / waitpid的话,那么保留的那段信息就不会释放,其进程号就会一直被占用,但是系统所能使用的进程号是有限的,如果大量的产生[僵死进程],将因为没有可用的进程号而导致系统不能产生新的进程. 此为僵尸进程的危害,应当避免。

 

转载于:https://www.cnblogs.com/wakee/p/10957555.html

最后

以上就是等待龙猫为你收集整理的python_day34_进程 并发进程 孤儿进程 僵尸进程的全部内容,希望文章能够帮你解决python_day34_进程 并发进程 孤儿进程 僵尸进程所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(49)

评论列表共有 0 条评论

立即
投稿
返回
顶部