什么是父进程

父进程 指的是创建并启动这个 music 子进程的那个进程

1. 具体解释

python 复制代码
import multiprocessing
import os
import time

def music(name, count):
    print(f'p2进程, 进程id: {os.getpid()}, '
          f'{multiprocessing.current_process().pid}, 父进程id: {os.getppid()}')
    for i in range(1, count + 1):
        time.sleep(0.1)

if __name__ == "__main__":
    # 这是父进程
    print(f"主进程(父进程)ID: {os.getpid()}")
    
    # 创建子进程
    p2 = multiprocessing.Process(target=music, args=("小明", 5))
    p2.start()
    p2.join()

输出示例:

复制代码
主进程(父进程)ID: 12345
p2进程, 进程id: 12346, 12346, 父进程id: 12345

可以看到:

  • music 进程的 PID 是 12346
  • 它的父进程 ID 是 12345,正是主进程

2. 进程树状关系

复制代码
操作系统
  └── Python解释器(主进程,PID: 12345)← 这是父进程
        └── 子进程(music函数,PID: 12346)← 这是子进程

3. 验证父进程关系

python 复制代码
import multiprocessing
import os
import time

def worker(name):
    print(f"子进程 {name}:")
    print(f"  自己的PID: {os.getpid()}")
    print(f"  父进程PID: {os.getppid()}")
    print(f"  父进程的父进程: {os.getppid()} 的父进程是?")
    time.sleep(1)

if __name__ == "__main__":
    print(f"主进程PID: {os.getpid()}")
    
    # 创建子进程
    p = multiprocessing.Process(target=worker, args=("A",))
    p.start()
    p.join()
    
    # 验证:os.getppid() 在主进程中返回什么?
    print(f"主进程的父进程PID: {os.getppid()}")  # 这会是启动Python的shell/PID

4. 多级父子关系

python 复制代码
import multiprocessing
import os
import time

def level2():
    """第二级子进程"""
    print(f"第2级进程: PID={os.getpid()}, 父进程={os.getppid()}")
    time.sleep(1)

def level1():
    """第一级子进程"""
    print(f"第1级进程: PID={os.getpid()}, 父进程={os.getppid()}")
    p = multiprocessing.Process(target=level2)
    p.start()
    p.join()

if __name__ == "__main__":
    print(f"主进程(根父进程): PID={os.getpid()}")
    p = multiprocessing.Process(target=level1)
    p.start()
    p.join()

输出:

复制代码
主进程(根父进程): PID=100
第1级进程: PID=101, 父进程=100    ← 父进程是主进程
第2级进程: PID=102, 父进程=101    ← 父进程是第1级进程

进程树:

复制代码
PID:100 (主进程)
  └── PID:101 (level1子进程)
        └── PID:102 (level2子进程)

5. 特殊情况和注意事项

情况1:孤儿进程

python 复制代码
import multiprocessing
import os
import time

def orphan():
    """子进程的父进程结束后,成为孤儿进程"""
    print(f"孤儿进程: PID={os.getpid()}, 父进程={os.getppid()}")
    time.sleep(3)  # 等待父进程结束
    print(f"父进程结束后: PID={os.getpid()}, 新父进程={os.getppid()}")
    # 父进程ID会变成1(init/systemd)或其他init进程

if __name__ == "__main__":
    p = multiprocessing.Process(target=orphan)
    p.start()
    # 主进程快速结束,不等待子进程
    print("主进程结束")

情况2:僵尸进程

python 复制代码
import multiprocessing
import os
import time

def zombie():
    print(f"子进程运行中: PID={os.getpid()}")
    time.sleep(2)

if __name__ == "__main__":
    p = multiprocessing.Process(target=zombie)
    p.start()
    time.sleep(1)
    # 父进程没有调用 join(),子进程结束后可能变成僵尸
    print(f"父进程: {os.getpid()}, 子进程结束但未回收")
    # 应该调用 p.join() 来回收子进程

情况3:在不同操作系统上的行为

python 复制代码
import multiprocessing
import os
import sys

def show_parent():
    print(f"进程: {os.getpid()}, 父进程: {os.getppid()}")

if __name__ == "__main__":
    print(f"Python PID: {os.getpid()}")
    
    # Windows 和 Linux/Unix 上创建进程的方式不同
    if sys.platform == 'win32':
        print("Windows: 使用 spawn 方式创建进程")
    else:
        print("Linux/Unix: 使用 fork 方式创建进程")
    
    p = multiprocessing.Process(target=show_parent)
    p.start()
    p.join()

6. 实际应用中的父进程概念

示例:进程池中的父进程

python 复制代码
from multiprocessing import Pool
import os

def worker(x):
    print(f"工作进程: {os.getpid()}, 父进程: {os.getppid()}")
    return x * 2

if __name__ == "__main__":
    print(f"主进程(父进程): {os.getpid()}")
    
    # 创建进程池,子进程的父进程是主进程
    with Pool(processes=3) as pool:
        results = pool.map(worker, [1, 2, 3])
    
    print(f"结果: {results}")

示例:守护进程

python 复制代码
import multiprocessing
import os
import time

def daemon_worker():
    """守护进程:父进程结束后自动终止"""
    print(f"守护进程启动: PID={os.getpid()}, 父进程={os.getppid()}")
    try:
        while True:
            time.sleep(1)
            print(f"守护进程运行中...")
    except Exception as e:
        print(f"守护进程被终止")

if __name__ == "__main__":
    print(f"主进程: {os.getpid()}")
    
    p = multiprocessing.Process(target=daemon_worker)
    p.daemon = True  # 设置为守护进程
    p.start()
    
    time.sleep(2)
    print("主进程结束,守护进程也会自动结束")

7. 获取和管理父进程

python 复制代码
import multiprocessing
import os
import signal

def child_process():
    """子进程可以获取父进程信息并与之交互"""
    parent_pid = os.getppid()
    print(f"子进程 {os.getpid()}, 父进程 {parent_pid}")
    
    # 检查父进程是否还存活
    try:
        os.kill(parent_pid, 0)  # 发送信号0测试进程是否存在
        print("父进程还在运行")
    except OSError:
        print("父进程已经结束")

def parent_process():
    """父进程管理子进程"""
    print(f"父进程: {os.getpid()}")
    p = multiprocessing.Process(target=child_process)
    p.start()
    p.join()
    
    # 父进程可以终止子进程
    if p.is_alive():
        p.terminate()  # 发送终止信号

if __name__ == "__main__":
    parent_process()

总结

  • 父进程 = 创建并启动当前进程的进程
  • multiprocessing 中,通常是主进程(if __name__ == "__main__" 中的代码)
  • 使用 os.getppid() 获取父进程 ID
  • 子进程可以通过父进程 ID 进行进程间通信和管理
  • 当父进程结束时,子进程可能成为孤儿进程或被强制终止(守护进程)
  • 正确管理父子进程关系对避免僵尸进程和资源泄漏很重要
相关推荐
IT_陈寒几秒前
Vue的响应式什么时候会失灵?这个坑我踩了
前端·人工智能·后端
Mark-Wang24 分钟前
2026大厂AI Agent高频面试题Top50:题目+参考答案+追问陷阱
人工智能
五度易链-区域产业数字化管理平台42 分钟前
WorkBuddy 实战:将带 MD5 签名的第三方 API 封装为 MCP 服务(企业模糊搜索接口案例)
大数据·人工智能·mcp
怪奇云呼军1 小时前
知识库也会注入指令?闪电智能VoiceAgent 如何防住 Prompt Injection
人工智能·python·算法·云计算·音视频
xushichang123_1 小时前
企业降本刚需下,云上模型蒸馏与轻量化部署怎么选?AWS“大模型教研+小模型推理” 路径
大数据·人工智能
EasyDSS1 小时前
开会不用装App:私有化音视频系统EasyDSS即时视频会议,浏览器点开就能聊,AI帮你写纪要
人工智能·音视频
阿里云大数据AI技术1 小时前
基于 EMR Serverless Ray 实现 Qwen 模型批量推理实践
人工智能·算法·agent
ZJU_统一阿萨姆1 小时前
【算子开发】环境搭建与第一个CUDA程序
开发语言·人工智能·系统架构
老登为啥喜欢吹AI1 小时前
继DSH之后!Codex Harness 也开源了!Rust 核心、三层架构、人机协作
人工智能