一. 进程的概念:
进程(有时称为重量级进程)则是一个执行中的程序。每个进程都拥有自己的地址空间、内存、数据栈以及其他用于跟踪执行的辅助数据。操作系统管理其上所有进程的执行,并为这些进程合理地分配时间。进程也可以通过派生(fork 或 spawn)新的进程来执行其他任务,不过因为每个新进程也都拥有自己的内存和数据栈等,所以只能采用进程间通信(IPC)的方式共享信息.
每一个进程都具备2个重要特性:
任务的可调度性: task_struct
资源的独立性: memory_map
二. Linux 进程状态图
◇ R : 运行中或可被运行的状态
◇ S : 可中断的等待态
◇ D : 不可中断的等待态
◇ Z : 僵尸态
◇ T : 停止态
三. 几种常见进程状态
1. 孤儿进程: 子进程还未运行完成,父进程就结束运行退出,留下的子进程就是孤儿进程。父进程死掉后,孤儿进程会被别的进程收养,通常是init进程(pid为1)。
守护进程,实际就是孤儿进程。
2. 僵尸进程: 子进程运行完成,但是父进程迟迟没有进行回收,此时子进程实际上并没有退出,其仍然占用着系统资源,这样的子进程称为僵尸进程。因为僵尸进程的资源一直未被回收,造成了系统资源的浪费,过多的僵尸进程将造成系统性能下降,所以应避免出现僵尸进程。僵尸进程的状态是Z。
四. 其他概念:
多任务的耗时点:
1. 产生任务载体(进程空间)
2. 任务切换
2.1 调度资源切换(task_struct结构体的维护)
2.2 进程的内存映射表的切换(memory_map结构的维护)
3. 任务载体回收资源
并发: 一个时间段内,多个任务都被执行了, 单核CPU
并行: 一个时间点内,多个任务都被执行了, 多核CPU时,
五. 多进程编程
"""1.一般方式"""
import random
import time
from functools import wraps
from multiprocessing import Process
# 模拟一个迅雷的下载任务的系统
# 设置一个全局状态标志
flags = 0
# 设计一个统计函数执行时间的装饰器
def cnt_time(old_fun):
@wraps(old_fun)
def wrapper(*args, **kwargs):
start_time = time.time()
ret = old_fun(*args, **kwargs)
end_time = time.time()
print("函数运行了{}秒".format(end_time - start_time))
return ret
return wrapper
def http_down_task(task_name):
global flags
print("开始下载{}任务".format(task_name))
flags = random.randint(1, 4)
time.sleep(flags)
print("下载{}任务完成,该任务消耗时间{}".format(task_name, flags))
@cnt_time
def multi_process():
print("欢迎使用模拟下载器")
tasks = []
for x in range(5):
p1 = Process(target=http_down_task, args=["task_{}".format(x+100)])
p1.start()
tasks.append(p1)
# 等待5个任务的全部结束
for task in tasks:
task.join()
print("任务结束了")
if __name__ == '__main__':
# main_process()
multi_process()
"""
TypeError: http_down_task() missing 1 required positional argument: 'task_name'
# 运行特点:
资源是独立的,不需要考虑某个任务修改全局变量,会影响到另外的任务的执行
独立的memory_map,切换任务时,不仅仅要切换task_struct,还要更新memory_map
"""
"""2.多进程面向对象写法"""
from multiprocessing import Process
import random
import time
# 构造一个自己的任务类
class HttpTaskProcess(Process):
def __init__(self, name):
super(HttpTaskProcess, self).__init__()
self.task_name = name
def run(self):
print("开始下载{}任务".format(self.task_name))
time.sleep(random.randint(1, 4))
print("下载{}任务完成".format(self.task_name))
def multi_process():
print("主任务开始")
tasks = []
for x in range(5):
p1 = HttpTaskProcess("Task{}".format(x))
p1.start()
tasks.append(p1)
# 等待任务的结束
for task in tasks:
task.join()
print("主任务结束")
if __name__ == '__main__':
multi_process()
"""3.使用进程池创建多进程"""
from multiprocessing import Pool, current_process
import random
import time
def task(msg):
print("我在{}进程的ID上".format(current_process().pid))
print("任务信息:", msg)
time.sleep(random.randint(1, 3))
print("任务{}执行完毕".format(current_process().pid))
task_pool = Pool(3)
def add_one_test():
task_pool.apply_async(task, args=("参数1",))
print("....")
task_pool.close()
task_pool.join()
def multi_process():
for x in range(10):
task_pool.apply_async(task, args=("参数{}".format(x),))
# input('...end...')
task_pool.close()
task_pool.join()
if __name__ == '__main__':
multi_process()
六. 进程间通信(IPC,Inter-Process Communication)
进程和线程,以及进程间通信和线程通信更详细信息建议参考https://blog.csdn.net/weixin_41207499/article/details/80599135