进程

1. 进程: 就是正在运行的程序,它是操作系统中,资源分配的最小单位.
    资源分配:分配的是cpu和内存等物理资源
    进程号是进程的唯一标识

    同一个程序执行两次之后是两个进程, 进程和进程之间是数据彼此隔离,通过socket通信

    并发是一个cpu同一时间不停执行多个程序, 并行是多个cpu同一时间不停执行多个程序

2. cpu的进程调度方法: 

    先来先服务fcfs(first come first server):先来的先执行
    短作业优先算法:分配的cpu多,先把短的算完
    时间片轮转算法:每一个任务就执行一个时间片的时间.然后就执行其他的.
    多级反馈队列算法

    越是时间长的,cpu分配的资源越少,优先级靠后
    越是时间短的,cpu分配的资源越多

3. 进程三状态: 

(1)就绪(Ready)状态
只剩下CPU需要执行外,其他所有资源都已分配完毕 称为就绪状态。
(2)执行(Running)状态
cpu开始执行该进程时称为执行状态。
(3)阻塞(Blocked)状态
由于等待某个事件发生而无法执行时,便是阻塞状态,cpu执行其他进程.例如,等待I/O完成input、申请缓冲区不能满足等等。

4. 同步 异步 / 阻塞 非阻塞: 

场景在多任务当中
同步:必须等一个任务完成,再进行下一个任务,只有一条主线,就是同步
异步:没等一个任务完成,就进行下一个任务,有两条主线,就是异步
阻塞:比如代码有了input,就是阻塞,必须要输入一个字符串,否则代码不往下执行
非阻塞:没有任何等待,正常代码往下执行.

同步阻塞 :效率低,cpu利用不充分
异步阻塞 :比如socketserver,可以同时连接多个,但是彼此都有recv
同步非阻塞:没有类似input的代码,从上到下执行.默认的正常情况代码
异步非阻塞:效率是最高的,cpu过度充分,过度发热 液冷

 

5. 进程的基本用法:

import os
# 获取当前进程进程号(子进程)
res = os.getpid()
print(res) # 2856

# 获取当前进程的父进程的id
res = os.getppid()
print(res) # 9648  pycharm的id

# 进程使用的语法
from multiprocessing import Process
def func():
    print("1子进程id是{},2父进程id是{}".format(os.getpid(),os.getppid()))

if __name__ == "__main__":
    print("3子进程id是{},4父进程id是{}".format(os.getpid(),os.getppid()))
    p = Process(target = func) # 创建子进程,返回一个进程对象
    p.start() # 调用子进程
"""
9992
9648
3子进程id是9992,4父进程id是9648
2368
9992
1子进程id是2368,2父进程id是9992
"""

6. 创建有参数的进程:

from multiprocessing import Process
import os
def func(n):
    for i in range(1,n+1):
        print("3子进程id是{},4父进程id是{}".format(os.getpid(),os.getppid()))

if __name__ == "__main__":
    print("1子进程id是{},2父进程id是{}".format(os.getpid(), os.getppid()))
    n = 5
    p = Process(target=func,args=(n,))
    p.start()
    for i in range(1,n+1):
        print("*"*i)

7. 进程之间的数据是隔离的:

from multiprocessing import Process
import os

time = "现在"
def func():
    global time
    time = "未来"
    print("111我是子进程{}".format(time))

if __name__ == "__main__":
    print("222我是主进程{}".format(time))
    p = Process(target=func)
    p.start()

8. 多个进程的异步并发:

# 多个进程的异步并发
from multiprocessing import Process
import os
def func(args):
    print("1子进程id是{},2父进程id是{}".format(os.getpid(), os.getppid()),args)

if __name__ == "__main__":
    for i in range(1,8):
        p = Process(target=func,args=(i,))
        p.start()

    print("主进程结束...")
"""
主进程结束...
1子进程id是10776,2父进程id是6204 1
1子进程id是2980,2父进程id是6204 2
1子进程id是612,2父进程id是6204 5
1子进程id是7748,2父进程id是6204 4
1子进程id是7132,2父进程id是6204 3
1子进程id是5988,2父进程id是6204 6
1子进程id是13296,2父进程id是6204 7
"""
"""
 程序在异步并发任务时,因为cpu调度策略问题,不一定先执行谁或者后执行谁,
整体而言,主进程速度快于子进程,cpu遇到阻塞立刻切换其他任务,等到进程的就绪态在切换回来

 主程序会默认等待所有的子进程执行结束之后,在关闭程序,释放资源
若不等待,子进程并不方便管理,容易造成僵尸进程,在后台不停的占用系统的资源(cpu和内存),不清楚进程的来源.
"""

 

9. join的使用:join的功能是让所有的子进程全部执行完之后,父进程再执行

# 基本用法
from multiprocessing import Process
def func():
    print("第一个")

if __name__ == "__main__":
    p = Process(target=func)
    p.start()
    p.join() # 待子进程执行完后,再执行父进程,对父进程有一个阻塞的作用

    print("第二个")
# 第一个
# 第二个


# 多个子进程配合使用
from multiprocessing import Process

def func(args):
    print("时间",args)

if __name__ == "__main__":
    lst = []
    for i in range(1,8):
        p = Process(target=func,args=(i,))
        p.start()
        lst.append(p)
    for j in lst:
        # print(j)
        j.join()

    print("时间结束!")

 

10. 使用自定义的类创建进程

# 基本语法无参数
import os
from multiprocessing import Process
class Myprocess(Process): # 必须继承Process父类
    def run(self): # 方法必须是run方法
        print("1子进程id是{},2父进程id是{}".format(os.getpid(), os.getppid()))

if __name__ == "__main__":
    p = Myprocess()
    p.start()
    print("3子进程id是{},4父进程id是{}".format(os.getpid(), os.getppid()))


# 带参数的
import os
from multiprocessing import Process
class Myprocess(Process): # 必须继承Process父类
    def __init__(self,arg):
        self.arg = arg
        super().__init__() # 使用super()去调用Process父类里面的构造方法,不然自定义不了
    def run(self): # 方法必须是run方法
        print("1子进程id是{},2父进程id是{}".format(os.getpid(), os.getppid()),self.arg)

if __name__ == "__main__":
    p = Myprocess("带参数的")
    p.start()
    print("3子进程id是{},4父进程id是{}".format(os.getpid(), os.getppid()))

 

11. 守护进程:守护的是主进程,在主进程执行完毕后,守护进程也会被终止

# 基本用法
from multiprocessing import Process
for i in range(2):
    print("子程序打印{}".format(i))

if __name__ == "__main__":
    p = Process()
    p.daemon = True # 设置为True代表设置这个子程序为守护进程,必须设置在start调用之前
    p.start()
# 子程序打印0
# 子程序打印1  主程序执行完后子程序就马上被终止,还没来得及执行


# 多个子进程
from multiprocessing import Process
import time
def func1():
    for i in range(1,3):
        print("第{}个".format(i))

def func2():
    print(666)
    print(888)

if __name__ == "__main__":
    p1 = Process(target=func1)
    p2 = Process(target=func2)
    p1.start()
    p2.daemon = True
    p2.start()
    time.sleep(1)  # 因有延时,所以守护进程才有时间打印出结果
    func1()

 

12. 守护进程实际应用:监控报活

from multiprocessing import Process
import time
def alive():
    while True:
        time.sleep(0.5) # 假设每隔0.5秒,报告一次服务器正常工作
        print("服务器功能正常!")

def func():
    time.sleep(5) # 假设5秒后此服务器发生异常
    print("我是负责记录数据的服务器!")

if __name__ == "__main__":
    p1 = Process(target=alive)
    p2 = Process(target=func)
    p1.daemon = True
    p1.start()
    p2.start()
    p2.join()

    print("主程序结束...")

 

posted on 2020-06-09 19:51  fdsimin  阅读(151)  评论(0编辑  收藏  举报