多进程编程

一.    进程的概念:
进程(有时称为重量级进程)则是一个执行中的程序。每个进程都拥有自己的地址空间、内存、数据栈以及其他用于跟踪执行的辅助数据。操作系统管理其上所有进程的执行,并为这些进程合理地分配时间。进程也可以通过派生(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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值