【python基础】十八、Python process 进程

进程 线程 协程

并发: 一个cpu, 轮流交替进行多线程
并行: 多个cpu, 同时执行,或 同时并发执行

进程 > 线程 > 协程 > 生成器

都可以实现多任务: 与特点有关

  • 任务比较多 用进程
  • 爬虫 用线程 或 协程

进程(Process),操作系统结构的基础,
曾经,面向进程设计的计算机结构中,进程就是程序的基本执行实体.(一个c)
当代,面向线程设计的计算机结构中,进程是线程的容器
* 优点
* 缺点

  • linux下 使用 fork 函数创建进程 os模块的fork
  • windows 使用 multiprocessing模块
  • 多进程 能否 访问 同一个全局变量?

    • 能, 仅仅 复制 全局变量 到自己进程, 不共用
  • 耗时用 线程 - 下载

  • 计算用 进程 - 运算

import os
import time
from multiprocessing import Process

n = 5   #


def download(t):
    global n    # 只是取到全局n的初始值, 不与task_2 共用
    while True:
        n -= 1.8
        print(' -- SonProcess Task 1', os.getpid(), '-', os.getppid(), 'n:', n)
        time.sleep(t)


def getfile(t):
    global n
    while True:
        n += 0.75
        print(' -- SonProcess Task 2', os.getpid(), '-', os.getppid(), 'n:', n)
        time.sleep(t)


if __name__ == '__main__':
    print('MainProcess', n)
  download# 错的
    p_1 = Process(target=download, args=(1,))     # 进程的 声明
    p_2 = Process(target=getfile, args=(2,))

    p_1.start()     # 进程的 祁东
    p_2.start()
    while n >= 0:
        n -= 1
        print('MainProcess', n)     # 此时共3个进程: 主进程 子进程1 2
        time.sleep(2)
    p_2.terminate()     # 子进程的 关闭
    p_1.terminate()

    # 主进程 运行到此, 关闭

自定义进程

import random
from multiprocessing import Process
from time import sleep


class MyProcess(Process):

    def __init__(self, c_name):  # 如果想 传入参数
        super(MyProcess, self).__init__()
        self.cname = c_name

    # 重写 run 方法
    def run(self):
        n = 1
        while True:
            t = random.choice([0.3, 0.5, 0.8, 1])
            print('进程:{} -- n: {} [{}] -- t:'.format(self.name, n, self.cname), t)
            n += 1
            sleep(t)
            # self.name 自动命名


if __name__ == '__main__':
    p0 = MyProcess('尚尚')
    p1 = MyProcess('唐唐')

    p0.start()
    p1.start()

pool

子进程数量不多-> multiprocess 的 Process 动态生成即可
上千个子进程 -> multiprocess 的 pool 方法

初始化pool 指定 最大进程数, 新请求提交, 自动创建进程.
进程数达到最大值, 该请求等待 ( 网盘 多个文件同时下载)

阻塞式: 添加一个,执行一个. 执行结束后 返回个啥  
非阻塞式: 一起添加到队列,立刻返回. 执行结束后, 回调 携带结果  

pool.apply_async()  非阻塞模式   一起来
pool.apply()        阻塞模式    一个一个来
def task_1(task_name):
    return retu_str


def call_back(n): 
    pass

if __name__ == '__main__':
    pool = Pool(4)

    tasks = ['吃饭', '睡觉', '打豆豆', '看书', '打代码', '啪啪啪-2', '吃饭饭2', '睡觉觉2', '打豆豆豆豆', '看书书', '打代码码码', '啪啪啪']
    for i in tasks:
        # pool.apply()
        pool.apply_async(task_1, args=(i,), callback=call_back)  # 非阻塞 异步

    # 进程池 依赖于 主进程, 阻止main结束
    pool.close()  # 进程池 任务 结束
    pool.join()  # 阻止 主进程 结束

进程间通信 Queue队列

后面笔记 就乱写了, 贴代码吧

from multiprocessing import Queue
q = Queue(8)
q.put()
q.get()
q.full()
q.empty()
q.put_nowait()
q.get_nowait()
# queue
import random
import time
from multiprocessing import Queue, Process

def download(q):
    for i in range(100):
        t = random.random() * 2
        f = str(i) + '.jpg'
        print('- 正在下载 -- ', f)
        time.sleep(t)
        q.put(f)
        print('-- 下载完成 -- ', f, ' 用时:', round(t, 2), 's')


def getfile(q):
    while True:
        if not q.empty():
            time.sleep(1)
            print('--- 获取文件 -- ', q.get(), ' 剩余文件', q.qsize(), '个')


if __name__ == '__main__':
    q = Queue(5)

    p_1 = Process(target=download, args=[q])  # 进程的 声明
    p_2 = Process(target=getfile, args=[q])

    p_1.start()
    p_2.start()

    p_1.join()
    p_2.join()
    p_2.terminate()  # 子进程的 关闭
    p_1.terminate()

    # queue 依赖 主进程 运行到此, 释放了q

在b站学习中

个人主页

学习链接

欢迎 批评 指正

### Python `multiprocessing.Process` 的使用方法及示例 #### 方法概述 在 Python 中,`multiprocessing.Process` 是实现多进程的核心类之一。它允许开发者通过创建独立的子进程来执行特定的任务[^2]。每个子进程拥有自己的内存空间,因此不会与其他进程共享全局变量。 以下是 `Process` 类的主要参数说明: - **target**: 可调用的对象(通常是函数),表示新进程中要运行的目标任务。 - **args**: 传递给目标函数的位置参数元组。 - **kwargs**: 传递给目标函数的关键字参数字典。 - **daemon**: 设置守护进程标志,默认为 False。如果设置为 True,则当父进程终止时,子进程会自动被销毁而不等待其完成。 #### 示例代码 下面是一个简单的例子展示如何使用 `multiprocessing.Process` 创建和启动一个新的进程: ```python from multiprocessing import Process import os def info(title): print(f"{title} - PID: {os.getpid()}") def f(name): info('function f') print(f'hello {name}') if __name__ == '__main__': info('main line') p = Process(target=f, args=('bob',)) p.start() p.join() # 主程序在此处阻塞直到子进程结束 ``` 在这个例子中,我们定义了一个名为 `f` 的函数作为子进程中的主要逻辑,并将其传入到 `Process` 实例化过程中。最后通过调用 `p.start()` 启动这个新的进程[^3]。 #### 守护进程行为分析 关于守护进程的行为特性,在某些场景下可能需要注意。例如,当设置了 `p.daemon=True` 并且父进程提前退出的情况下,即使子进程尚未完成工作也会立即被强制关闭。这可以通过如下实验验证: ```python from multiprocessing import Process import time def worker(): try: while True: print("Worker is running...") time.sleep(1) except KeyboardInterrupt: print("Stopping gracefully.") if __name__ == "__main__": process = Process(target=worker) process.daemon = True # 设定为守护模式 process.start() time.sleep(5) # 让主线程短暂休眠几秒后再退出 print("Main process exiting.") ``` 上述脚本展示了当主进程仅存活五秒钟之后便自行终结的情形下,尽管子进程仍在尝试循环输出日志消息,但由于它是作为一个守护进程存在,故随着主进程消亡而被迫停止运作。 #### 数据共享解决方案 对于需要跨不同进程间交换数据的需求来说,单独依靠基本类型的副本拷贝显然是不够高效的;此时可借助于 `multiprocessing.Manager` 提供的功能构建更为复杂的结构体来进行通信与同步控制[^4]。比如下面的例子演示了怎样利用管理器生成一个可供多方读写的列表容器: ```python from multiprocessing import Manager, Process def add_items(lst): lst.append("Item added by subprocess!") if __name__ == '__main__': with Manager() as manager: shared_list = manager.list(['Initial item']) proc = Process(target=add_items, args=(shared_list,)) proc.start() proc.join() print(shared_list) ``` 这里采用了上下文管理的方式确保资源能够得到妥善释放的同时也简化了异常处理流程的设计复杂度。 ---
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值