ZetCode

Python os.getpid 函数

上次修改时间:2025 年 4 月 11 日

本篇综合指南探讨 Python 的 os.getpid 函数,该函数检索当前进程 ID。我们将介绍 PID 的使用、进程管理和实际示例。

基本定义

os.getpid 函数返回当前进程的进程 ID (PID)。 PID 是分配给每个正在运行的进程的唯一编号。

操作系统使用 PID 来识别和管理进程。 它们对于进程间通信和进程控制至关重要。

获取当前进程 ID

os.getpid 最简单的用法是检索当前 Python 进程的 PID。 这对于日志记录和进程识别非常有用。

basic_pid.py
import os

# Get the current process ID
current_pid = os.getpid()
print(f"The current process ID is: {current_pid}")

# Verify PID with system tools
print("Run 'ps aux | grep python' in terminal to verify")

此示例演示了如何获取 PID 并建议使用系统工具进行验证。 每次运行脚本时,PID 都会不同。

PID 由操作系统按顺序分配,并在达到最大值时循环使用。

在日志记录中使用 PID

进程 ID 在日志记录中很有价值,可以区分同一程序的多个实例。 这有助于调试和监控。

pid_logging.py
import os
import logging

# Configure logging with PID
logging.basicConfig(
    format='%(asctime)s [PID:%(process)d] %(message)s',
    level=logging.INFO
)

# Get PID and log it
pid = os.getpid()
logging.info(f"Application started with PID: {pid}")

# Simulate some work
for i in range(3):
    logging.info(f"Processing item {i}")

此示例配置日志记录以在每条消息中包含进程 ID。 %(process)d 格式说明符自动包含 PID。

运行多个实例时,日志将清楚地显示哪个进程生成了每条消息。

比较父进程和子进程 PID

创建子进程时,每个进程都会获得一个唯一的 PID。 此示例显示了父进程和子进程 ID 之间的差异。

parent_child_pid.py
import os
import time
from multiprocessing import Process

def child_task():
    print(f"Child process PID: {os.getpid()}")
    time.sleep(2)

if __name__ == "__main__":
    print(f"Parent process PID: {os.getpid()}")
    
    # Create child process
    child = Process(target=child_task)
    child.start()
    child.join()
    
    print("Child process finished")

父进程在创建子进程之前打印其 PID。 子进程打印自己的 PID,该 PID 与父进程的 PID 不同。

这表明每个进程(即使是相关的进程)都有一个唯一的标识符。

进程管理中的 PID

PID 对于进程管理至关重要。 此示例演示了如何使用 PID 将信号发送到进程。

process_management.py
import os
import signal
import time
from multiprocessing import Process

def worker():
    print(f"Worker PID: {os.getpid()}")
    while True:
        time.sleep(1)

if __name__ == "__main__":
    p = Process(target=worker)
    p.start()
    
    print(f"Main PID: {os.getpid()}")
    print(f"Worker process created with PID: {p.pid}")
    
    time.sleep(3)
    print("Terminating worker process")
    os.kill(p.pid, signal.SIGTERM)
    p.join()

这会创建一个工作进程,获取其 PID,然后使用 os.kill 终止它。 PID 对于定位正确的进程至关重要。

终止等进程管理操作需要正确的 PID,以避免影响其他进程。

单例应用程序的 PID 文件

PID 文件确保只有一个应用程序实例运行。 此示例演示了创建和检查 PID 文件。

pid_file.py
import os
import sys

PID_FILE = "app.pid"

def check_pid_file():
    if os.path.exists(PID_FILE):
        with open(PID_FILE, "r") as f:
            old_pid = int(f.read())
        
        # Check if process still running
        try:
            os.kill(old_pid, 0)
            print(f"Application already running with PID: {old_pid}")
            sys.exit(1)
        except OSError:
            # Process not running, remove stale PID file
            os.remove(PID_FILE)
    
    # Create new PID file
    with open(PID_FILE, "w") as f:
        f.write(str(os.getpid()))

if __name__ == "__main__":
    check_pid_file()
    print(f"Application started with PID: {os.getpid()}")
    input("Press Enter to exit...")
    os.remove(PID_FILE)

该脚本检查是否存在 PID 文件。 如果找到,它会验证该进程是否仍在运行,然后再允许新的实例。

此模式对于应该只运行一次的守护进程和服务很常见。

线程识别中的 PID

虽然线程共享相同的 PID,但可以通过其他信息来识别它们。 此示例显示了线程和进程识别。

thread_pid.py
import os
import threading
import time

def worker():
    print(f"Thread {threading.get_ident()} in process {os.getpid()}")
    time.sleep(1)

if __name__ == "__main__":
    print(f"Main thread in process {os.getpid()}")
    
    # Create multiple threads
    threads = []
    for i in range(3):
        t = threading.Thread(target=worker)
        threads.append(t)
        t.start()
    
    for t in threads:
        t.join()

所有线程都显示相同的 PID,因为它们属于同一进程。 threading.get_ident() 提供特定于线程的标识。

这表明 PID 标识进程,而不是进程中的线程。

系统监控中的 PID

PID 用于监控每个进程的系统资源。 此示例演示了如何使用 PID 获取特定于进程的信息。

process_monitoring.py
import os
import psutil  # Requires psutil package

def show_process_info():
    pid = os.getpid()
    process = psutil.Process(pid)
    
    print(f"Process ID: {pid}")
    print(f"Process name: {process.name()}")
    print(f"Process status: {process.status()}")
    print(f"CPU percent: {process.cpu_percent()}%")
    print(f"Memory usage: {process.memory_info().rss / 1024 / 1024:.2f} MB")

if __name__ == "__main__":
    show_process_info()

这使用 psutil 库来获取有关当前进程的详细信息。 PID 用于标识要监控的进程。

系统监控工具通常使用 PID 来跟踪每个进程的资源使用情况和性能指标。

安全注意事项

最佳实践

资料来源

作者

我叫 Jan Bodnar,是一名充满热情的程序员,拥有丰富的编程经验。 自 2007 年以来,我一直在撰写编程文章。 迄今为止,我已经撰写了 1,400 多篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

列出所有 Python 教程