看langchain代码之前必备知识之 - Python 多进程: multiprocessing (3)


前言

上一篇文章介绍了如何启动和关闭多进程,其中使用了 multiprocessing的event来传递关闭信号,我们今天继续使用举例的方式,介绍它的使用。没有看过上一篇文章的朋友请查看上一篇文章。
看langchain代码之前必备知识之 - Python 多进程: multiprocessing (2)

我们这篇文章的代码是基于上一篇文章来修改的


一、使用multiprocessing的event实现进程的有序启动

在实际的程序里,我们通常需要控制程序的启动顺序,例如langchain-chatchat里是先启动模型,再启动api,然后再启动web-ui的,这样可以保证我们看到web界面后能直接使用,而不会出现模型还没准备好等等之类的影响使用体验的

二、实现步骤

1.修改task,添加start_event参数

代码如下:

def task(name, start_need_time, start_event: mp.Event = None, stop_event: mp.Event = None):
    print(name + ' 正在启动, 启动需要' + str(start_need_time) + '秒')
    sleep(start_need_time)
    print(name + ' 启动完成')
    start_event.set()
    while not stop_event.is_set():
        current_time = str(time.strftime('%H:%M:%S', time.localtime()))
        print(name + ' running ' + current_time)
        sleep(2)
    print(name + ' end')

2.修改启动程序

给每一个job生成一个 start event ,传递到子进程里。
使用 job1_start_event.wait() 的方式阻塞程序,直到job启动完成。
代码如下:

        if cmd == 'start':
            stop_event.clear()
            if 'Job1' not in process_list or process_list['Job1'].is_alive() is False:
                job1_start_event = mp.Event()
                process_list['Job1'] = Process(target=task, args=('Job1', 5, job1_start_event, stop_event))
                process_list['Job1'].start()
                job1_start_event.wait()
            else:
                print('任务已经在运行')
            if 'Job2' not in process_list or process_list['Job2'].is_alive() is False:
                job2_start_event = mp.Event()
                process_list['Job2'] = Process(target=task, args=('Job2', 2, job2_start_event, stop_event))
                process_list['Job2'].start()
                job2_start_event.wait()
            else:
                print('任务已经在运行')

三、效果

1. 启动

python test5.py

2.浏览器访问

在浏览器里访问http://localhost:8000/start之后,可以看到虽然job1的启动时间比job2长,但是依然是job1先启动,然后再启动job2

在这里插入图片描述


四、对应langchain-chatchat的部分

大家看完本文,可以去翻看如下的代码

在这里插入图片描述

总结

1. multiprocessing.Event 的四个主要方法

下面是 multiprocessing.Event 的四个主要方法及其用法的总结:

  • wait():

功能:阻塞当前进程,直到事件被设置。
用法:event.wait()

  • set():

功能:设置事件,将事件的内部标志位设置为 True。
用法:event.set()

  • clear():

功能:重置事件,将事件的内部标志位重置为 False。
用法:event.clear()

  • is_set():

功能:返回事件的当前状态,如果事件被设置为 True,则返回 True,否则返回 False。
用法:event.is_set()

这些方法允许你在多进程之间进行同步,控制进程的执行顺序,以及共享状态。通过使用这些方法,你可以更加灵活地控制多进程程序的行为,实现更复杂的并发逻辑。

2. 代码分享

由此,我们就实现了进程的有序启动。代码如下,需要的朋友可以参考

import time
from multiprocessing import Process
from time import sleep
import multiprocessing as mp
import uvicorn
from fastapi import FastAPI
import asyncio

# 从队列中获取命令
def get_cmd(from_queue):
    if not from_queue.empty():
        return from_queue.get()
    else:
        return ""

# 执行任务的函数
def task(name, start_need_time, start_event: mp.Event = None, stop_event: mp.Event = None):
    # 打印任务开始信息
    print(name + ' 正在启动, 启动需要' + str(start_need_time) + '秒')
    sleep(start_need_time)
    # 打印任务完成信息
    print(name + ' 启动完成')
    # 设置启动事件
    start_event.set()
    while not stop_event.is_set():
        # 打印任务运行信息
        current_time = str(time.strftime('%H:%M:%S', time.localtime()))
        print(name + ' running ' + current_time)
        sleep(2)
    # 打印任务结束信息
    print(name + ' end')

# Web 服务
def web_service(task_queue):
    app = FastAPI()

    @app.get("/start")
    async def start_task():
        # 将 start 命令放入队列
        task_queue.put('start')
        return "start!"

    @app.get("/stop")
    async def stop_task():
        # 将 stop 命令放入队列
        task_queue.put('stop')
        return "stop!"

    # 运行 FastAPI 服务
    uvicorn.run(app, host="0.0.0.0", port=8000)

# 任务管理器
async def task_manager(task_queue):
    # 创建并启动 Web 服务进程
    w = Process(target=web_service, args=(queue,))
    w.start()
    # 创建停止事件和进程列表
    stop_event = mp.Event()
    process_list = {}

    while True:
        # 获取命令
        cmd = get_cmd(task_queue)
        if cmd == 'start':
            # 清除停止事件
            stop_event.clear()
            # 如果任务不存在或者任务已经停止,则启动任务
            if 'Job1' not in process_list or process_list['Job1'].is_alive() is False:
                job1_start_event = mp.Event()
                process_list['Job1'] = Process(target=task, args=('Job1', 5, job1_start_event, stop_event))
                process_list['Job1'].start()
                job1_start_event.wait()
            else:
                print('任务已经在运行')
            if 'Job2' not in process_list or process_list['Job2'].is_alive() is False:
                job2_start_event = mp.Event()
                process_list['Job2'] = Process(target=task, args=('Job2', 2, job2_start_event, stop_event))
                process_list['Job2'].start()
                job2_start_event.wait()
            else:
                print('任务已经在运行')
        elif cmd == 'stop':
            # 设置停止事件
            stop_event.set()
            # 给10秒的时间,如果还不停下来,那就强制停止子进程了
            sleep(10)
            process_list['Job1'].terminate()
            process_list['Job2'].terminate()
            process_list['Job1'].join()
            process_list['Job2'].join()
            stop_event.clear()

if __name__ == '__main__':
    # 创建共享队列
    manager = mp.Manager()
    queue = manager.Queue()
    # 运行任务管理器
    loop = asyncio.get_event_loop()
    loop.run_until_complete(task_manager(queue))


<think>嗯,用户之前问过关于如何准备实习的详细计划,现在又问具体要学会哪些内容,感觉有点焦虑,可能之前的计划虽然详细,但内容太多,用户不知道从哪里下手,或者对需要掌握的具体知识点还不够明确。用户用了很多感叹词,比如“啊🙀啊啊啊”,说明他现在可能压力很大,需要更清晰的指导。 首先,我需要确定用户的学习方向,是AI、数据科学还是其他领域。根据之前的回复,用户可能是在准备机器学习或数据科学的实习,所以应该围绕这些领域展开。用户需要的是一个结构化的知识体系,明确每个部分需要学什么,以及为什么学这些。 然后,拆解核心技能。比如编程基础,Python是必须的,但还要考虑库和工具,比如Pandas、NumPy、Scikit-learn。数学基础方面,线性代数、概率统计、微积分这些是机器学习的基础。机器学习本身包括算法、评估指标、项目实战。深度学习可能需要框架如PyTorch或TensorFlow,以及具体的模型结构。工程化能力比如Git、Docker、Flask这些工具和部署知识也很重要。 接下来,要考虑用户的学习路径,分阶段来,从基础到进阶,再到专项领域。比如3个月打基础,6个月深入,最后分CV或NLP方向。同时,用户可能还需要面试准备和实战技巧,比如刷题和项目经验。 用户可能还担心如何选择方向,比如CV还是NLP,或者如何处理学习中的困难,比如代码跑不通。需要在回答中给出明确的步骤和建议,比如测试两个方向的小项目,看哪个更有兴趣,或者遇到问题时的解决流程。 最后,资源推荐也很重要,提供权威的书籍、课程链接,以及实用的速查表,帮助用户快速查找资料。同时,鼓励用户行动,减少焦虑,强调实践的重要性。</think>不用慌!直接给你划出 **「AI/数据科学方向必须掌握的技能树」**,按优先级排序并标注企业级高频需求(附学习资源+避坑指南)👇 --- ### 🎯 **【核心四大模块】必须死磕的内容** #### 1️⃣ **编程基础(占20%权重)** - **Python硬核部分**: - 列表推导式/生成器表达式(处理大数据时省内存) - 装饰器(@staticmethod, @classmethod 在框架中常见) - 多进程处理(`multiprocessing`库加速数据预处理) ```python # 企业级高频代码:用Pool加速计算 from multiprocessing import Pool def process_data(chunk): return chunk**2 if __name__ == &#39;__main__&#39;: with Pool(4) as p: results = p.map(process_data, [1,2,3,4]) ``` - **必学库**: - Pandas(掌握`groupby`/`pivot_table`/`merge`) - NumPy(广播机制+矩阵运算) - Matplotlib/Seaborn(特征分布可视化) #### 2️⃣ **数学基础(占15%权重)** - **线性代数**: - 奇异值分解(SVD在推荐系统中的应用) - 矩阵求导(推导神经网络梯度必备) $$ \frac{\partial}{\partial W} (XW - y)^T(XW - y) = 2X^T(XW - y) $$ - **概率统计**: - 贝叶斯定理(垃圾邮件分类核心) - 假设检验(AB测试评估指标显著性) #### 3️⃣ **机器学习(占35%权重)** - **算法深挖清单**: - 逻辑回归(搞懂sigmoid函数和交叉熵损失) - 随机森林(特征重要性计算原理) - XGBoost(手写目标函数二阶泰勒展开) - SVM(核技巧与对偶问题转化) - **企业级技能**: - 特征工程(分箱处理/时间序列特征构造) - 模型解释(SHAP值可视化) - 超参调优(Optuna框架实战) #### 4️⃣ **深度学习(占30%权重)** - **CV方向必学**: - CNN经典结构(ResNet的残差连接图示) ```python # PyTorch实现残差块 class ResidualBlock(nn.Module): def __init__(self, in_channels): super().__init__() self.conv1 = nn.Conv2d(in_channels, in_channels, 3, padding=1) self.bn1 = nn.BatchNorm2d(in_channels) self.conv2 = nn.Conv2d(in_channels, in_channels, 3, padding=1) self.bn2 = nn.BatchNorm2d(in_channels) def forward(self, x): residual = x out = F.relu(self.bn1(self.conv1(x))) out = self.bn2(self.conv2(out)) out += residual # 残差连接 return F.relu(out) ``` - **NLP方向必学**: - Transformer架构(多头注意力计算过程) - BERT微调技巧(CLS向量用于分类任务) - 文本生成(Beam Search算法) --- ### 🚩 **【企业级能力附加项】** #### 🔧 工程化能力 - Git协作(解决冲突/rebase操作) - Docker部署(编写Dockerfile最佳实践) - REST API开发(FastAPI搭建预测接口) #### 📊 业务理解 - 指标设计(如何定义用户流失率) - AB测试(样本量计算工具:[Evan’s Awesome A/B Tools](https://www.evanmiller.org/ab-testing/)- 因果推断(双重差分法DID实战) --- ### ⚠️ **「新手避坑指南」** 1. **不要死磕数学证明**:先会用再理解(如PCA先调sklearn的API,再研究特征值分解) 2. **警惕过时技术**: - 已淘汰:手动实现KNN(实际用faiss库加速) - 建议学:LangChain大模型应用开发 3. **项目误区**: - 差示例:只用MNIST数字识别(过于简单) - 好示例:COVID-CT图像分类([Kaggle数据集](https://www.kaggle.com/datasets/plameneduardo/covidct)--- ### 📚 **学习资源黄金组合** 1. **书籍**: - 《Hands-On Machine Learning》([GitHub代码](https://github.com/ageron/handson-ml2)- 《深度学习入门:基于Python的理论与实现》(鱼书) 2. **课程**: - 李沐《动手学深度学习》([B站视频](https://www.bilibili.com/video/BV1if4y1h7qw)- 吴恩达《机器学习2022新版》([Coursera链接](https://www.coursera.org/specializations/machine-learning-introduction)3. **工具速查**: - PyTorch张量操作速查表:[Cheat Sheet](https://pytorch.org/tutorials/beginner/ptcheat.html) - SQL必会50题:[LeetCode题库](https://leetcode.cn/problemset/sql/) --- ### 🚨 **紧急情况处理** 如果现在就要面试,优先掌握: 1. 用LightGBM完成一个完整项目(特征工程→调参→模型解释) 2. 手推逻辑回归梯度下降公式 3. 解释Transformer为什么比RNN好 **记住这个公式**:竞争力 = 算法理解深度 × 工程实现能力 × 业务敏感度 现在立刻打开PyCharm,从实现一个带残差连接的CNN开始!遇到报错时,把错误信息贴到[Python Error](https://stackoverflow.com/questions/tagged/python)标签下,你会发现90%的问题已有解决方案 💪
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值