os模块篇(十八)

os._exit(n)

os._exit(n) 是 Python 的一个内建函数,用于立即终止当前进程。这个函数与 sys.exit(n) 有所不同,主要表现在以下几点:

  • 终止进程的方式:

    • os._exit(n):这是一个更低级别的函数,它会立即终止当前进程,不执行任何清理操作,如 finally 块或 atexit 钩子。
    • sys.exit(n):这个函数会抛出一个 SystemExit 异常。如果这个异常在主程序中被捕获,那么程序可以执行一些清理操作然后退出。如果 SystemExit 异常没有被捕获,那么程序会终止。
  • 返回值:

    • os._exit(n):它接受一个整数作为参数,这个整数用作进程的退出状态。在 Unix 和 Linux 系统中,退出状态 0 通常表示成功,非零值表示出现了某种错误。
    • sys.exit(n):它也接受一个参数,但通常是一个对象,这个对象将被转换为 None 或一个整数,然后作为退出状态。
  • 用途:

    • os._exit(n):通常在子进程中使用,或者当你需要立即终止程序,而不关心任何后续清理工作时使用。
    • sys.exit(n):在大多数情况下,这是更合适的退出方式,因为它允许你执行一些清理工作,并可能捕获 SystemExit 异常以执行额外的逻辑。

注意:在 Python 的官方文档中,os._exit() 被标记为“内部使用”,这意味着它可能不是为公共使用而设计的,并且在未来的版本中可能会有所变化。因此,除非你有特殊的需求,否则通常建议使用 sys.exit()。

os.forkpty()

os.forkpty() 是 Python 的 os 模块中的一个函数,它用于创建一个新的进程,并且这个新进程会连接到一个伪终端(pseudo-terminal,简称 pty)。伪终端是一种在父进程和子进程之间提供类似终端行为的机制。os.forkpty() 主要用于实现类似 shell 那样的交互式环境。

函数的原型如下:

os.forkpty(master_fd, name, termios=None, winsize=None)

参数说明:

  • master_fd:一个可选的文件描述符,如果提供,则它会被设置为新创建的伪终端的主设备。如果不提供,函数会返回一个新的文件描述符。
  • name:一个可选的字符串,指定伪终端从设备的路径名。通常不需要指定,可以设置为 None。
  • termios:一个可选的 termios 结构体,用于设置从设备的终端属性。通常不需要指定,可以设置为 None。
  • winsize:一个可选的元组,用于设置从设备的窗口大小。通常不需要指定,可以设置为 None。

返回值:

  • 如果成功,该函数返回两次,一次在父进程中,一次在子进程中。在父进程中,它返回子进程的 PID。在子进程中,它返回 0。
  • 如果出现错误,则抛出 OSError 异常。

这是一个使用 os.forkpty() 的简单示例:

import os
import sys

def child_process():
    # 子进程中的代码
    print("Hello from child process!", file=sys.stderr)

if __name__ == "__main__":
    try:
        master_fd, slave_name = os.forkpty()
    except OSError as e:
        print(f"Failed to forkpty: {e}")
        sys.exit(1)

    if master_fd is not None:
        # 父进程中的代码
        pid, status = os.waitpid(master_fd, 0)
        if os.WIFEXITED(status):
            print(f"Child exited with code {os.WEXITSTATUS(status)}")
        elif os.WIFSIGNALED(status):
            print(f"Child terminated by signal {os.WTERMSIG(status)}")
    else:
        # 子进程中的代码
        child_process()
        os._exit(0)

在这个例子中,父进程创建了一个新的伪终端,并等待子进程结束。子进程通过标准错误输出打印一条消息,然后正常退出。父进程收集子进程的退出状态,并打印相关信息。

请注意,os.forkpty() 只在 Unix-like 系统(如 Linux、macOS)上可用,它不是 Windows 平台的一部分。

os.kill(pid, sig, /)

os.kill() 是 Python 的 os 模块中的一个函数,用于向指定的进程发送一个信号。这个函数接收两个参数:

  • pid:一个整数,表示要接收信号的进程的进程ID(PID)。
  • sig:一个整数,表示要发送的信号的类型。

在 Unix 和 Linux 系统上,信号是一种进程间通信的机制,它允许一个进程向另一个进程发送一个消息,以通知它某种事件的发生。这些信号可以是操作系统定义的,也可以是用户自定义的。例如,SIGKILL 信号用于立即终止进程,而 SIGTERM 信号用于请求进程正常终止。

os.kill() 函数将 sig 信号发送给 pid 指定的进程。如果进程成功接收到信号,则函数返回 None。如果进程不存在,或者进程没有权限接收该信号,则会引发 PermissionError 或 ProcessLookupError。

这里有一个简单的例子,演示了如何使用 os.kill() 函数发送 SIGTERM 信号来请求终止一个进程:

import os

# 假设你有一个进程ID,比如 1234
pid = 1234

# 发送 SIGTERM 信号给这个进程
try:
    os.kill(pid, os.SIGTERM)
    print(f"SIGTERM signal sent to process {pid}")
except ProcessLookupError:
    print(f"Process {pid} does not exist")
except PermissionError:
    print(f"Permission denied to send signal to process {pid}")

注意,不是所有的信号都可以被所有进程安全地接收。有些信号,如 SIGKILL(os.SIGKILL),只能由具有适当权限的进程(通常是超级用户)发送给其他进程。

在发送信号之前,你应当确保你了解信号的行为以及它可能对目标进程产生的影响。不当的信号使用可能会导致数据丢失、进程异常终止或其他不可预期的行为。

os.killpg(pgid, sig, /)

os.killpg(pgid, sig) 是 Python 的 os 模块中的一个函数,用于向指定的进程组发送一个信号。这个函数主要用于 Unix 和类 Unix 系统,如 Linux。

参数说明:

  • pgid:一个整数,表示要接收信号的进程组的 ID。
  • sig:一个整数,表示要发送的信号的类型。

在 Unix 和 Linux 系统上,进程可以被组织成进程组,每个进程组都有一个唯一的进程组 ID(PGID)。进程组允许用户通过向整个组发送信号来管理一组相关的进程。

os.killpg() 函数将 sig 信号发送给 pgid 指定的进程组中的所有进程。如果成功,函数返回 None;如果进程组不存在或无法发送信号,则会引发 OSError。

这是一个使用 os.killpg() 的简单示例:

import os

# 假设你知道一个进程组的 ID,比如 1234
pgid = 1234

# 发送 SIGTERM 信号给这个进程组中的所有进程
try:
    os.killpg(pgid, os.SIGTERM)
    print(f"SIGTERM signal sent to process group {pgid}")
except OSError as e:
    print(f"Failed to send signal to process group {pgid}: {e}")

请注意,发送信号到进程组需要适当的权限,并且不是所有的信号都可以安全地发送到所有类型的进程。不当的使用可能会导致系统不稳定或数据损坏。

此外,os.killpg() 只在 Unix-like 系统(如 Linux、macOS)上可用,它不是 Windows 平台的一部分。在 Windows 上,进程和进程组的概念与 Unix-like 系统有所不同,因此没有直接的等价函数。

os.nice(increment, /)

os.nice(increment) 是 Python 中 os 模块的一个函数,用于改变当前进程的“nice”值。在 Unix 和类 Unix 系统(如 Linux)中,nice 值是一个用于调整进程优先级的机制。nice 值范围通常是 -20(最高优先级)到 19(最低优先级)。

当你调用 os.nice(increment) 时,当前进程的 nice 值会增加 increment。如果 increment 是正数,那么进程的优先级会降低(即变得更加“nice”,意味着它会更少地占用 CPU 资源,让其他进程有更多的机会运行)。如果 increment 是负数,那么进程的优先级会提高。

这个函数通常用于那些不需要很多 CPU 资源的进程,或者那些希望主动降低自己优先级的进程。

这里是一个简单的示例:

import os

# 获取当前进程的 nice 值
current_nice = os.getpriority(os.PRIO_PROCESS, os.getpid())
print(f"Current nice value: {current_nice}")

# 增加 nice 值,降低进程优先级
os.nice(5)

# 再次获取 nice 值以确认改变
new_nice = os.getpriority(os.PRIO_PROCESS, os.getpid())
print(f"New nice value: {new_nice}")

在这个例子中,我们首先使用 os.getpriority() 函数获取当前进程的 nice 值,然后调用 os.nice(5) 来增加 nice 值,最后再次调用 os.getpriority() 来确认 nice 值已经改变。

请注意,os.nice() 的实际效果可能取决于操作系统的调度策略和其他因素,它并不保证一定会降低进程的优先级。此外,这个函数仅适用于 Unix 和类 Unix 系统,Windows 平台不支持此功能。

os.pidfd_open(pid, flags=0)

os.pidfd_open(pid, flags=0) 是 Python 的 os 模块中的一个函数,用于打开一个进程ID(PID)的文件描述符。这个函数在 Python 3.10 版本中引入,它提供了一种新的机制来跟踪和管理进程,特别是在子进程创建和父进程需要等待子进程结束的场景中。

参数说明:

  • pid:一个整数,表示要打开其文件描述符的进程的进程ID。
  • flags:一个可选的整数,用于指定打开文件描述符时的行为。默认为0,表示使用默认行为。

os.pidfd_open() 函数返回一个文件描述符(一个整数),它可以用于通过文件描述符接口来管理进程。例如,可以使用 os.read() 和 os.write() 函数来读取和写入文件描述符,或者使用 os.close() 函数来关闭文件描述符。

这个函数的主要用途是在父进程中跟踪子进程的状态。通过获取子进程的 PID 文件描述符,父进程可以等待子进程结束,而无需轮询或使用其他机制。此外,文件描述符可以传递给其他进程,从而提供了一种在进程之间传递进程ID的机制。

下面是一个简单的示例,演示了如何使用 os.pidfd_open() 函数来跟踪子进程的结束:

import os

# 创建一个子进程
pid = os.fork()

if pid == 0:
    # 子进程执行的代码
    print("Child process running with PID:", os.getpid())
else:
    # 父进程执行的代码
    # 获取子进程的 PID 文件描述符
    pidfd = os.pidfd_open(pid)
    
    # 等待子进程结束
    os.waitpid(pidfd, 0)
    
    # 关闭 PID 文件描述符
    os.close(pidfd)
    
    print("Child process has exited")

在这个示例中,父进程使用 os.fork() 创建了一个子进程。然后,父进程使用 os.pidfd_open() 获取子进程的 PID 文件描述符,并使用 os.waitpid() 等待子进程结束。最后,父进程关闭了 PID 文件描述符。

请注意,os.pidfd_open() 函数是 Python 3.10 中引入的新功能,因此在较旧的 Python 版本中可能不可用。此外,由于这个函数使用文件描述符来管理进程,因此在使用时需要注意文件描述符的管理和错误处理。

os.plock(op, /)

os.plock() 是 Python 的 os 模块中的一个函数,用于在文件上设置或释放建议性的锁。这个函数在 Python 3.3 版本中被引入,并且在某些操作系统上可能不可用。它提供了一个机制,允许程序在文件上设置一个锁,以防止其他程序同时访问该文件。

参数说明:

  • op:一个整数,表示要执行的操作。它可以是以下值之一:
    • os.PLOCK_ADVISE:设置建议性锁,以指示其他进程在尝试访问文件时应该考虑锁的存在。
    • os.PLOCK_ONFAULT:设置建议性锁,以在文件访问出错时通知调用进程。
    • os.PLOCK_OFFFAULT:释放之前设置的 os.PLOCK_ONFAULT 锁。
    • os.PLOCK_ADVISE_NONBLOCK:非阻塞版本的 os.PLOCK_ADVISE。

os.plock() 函数返回一个布尔值,指示操作是否成功。如果操作失败,它将返回 False,并可能设置全局错误变量 errno 来指示失败的原因。

下面是一个使用 os.plock() 的示例:

import os

# 打开一个文件用于读写
with open('example.txt', 'r+') as file:
    # 尝试在文件上设置一个建议性锁
    if os.plock(os.PLOCK_ADVISE):
        print("Lock successfully acquired")
        # 执行需要锁的操作
        # ...
        
        # 释放锁
        os.plock(os.PLOCK_OFFFAULT)
        print("Lock released")
    else:
        print("Failed to acquire lock")

在这个示例中,我们尝试在文件 example.txt 上设置一个建议性锁,并在成功获取锁后执行一些操作,然后释放锁。

需要注意的是,os.plock() 设置的锁是建议性的,这意味着它不会阻止其他进程实际访问文件。相反,它提供了一种机制,允许进程在尝试访问文件时检查锁的存在,并据此决定是否继续访问或等待。因此,它主要依赖于使用它的程序来遵守锁的存在,而不是由操作系统强制执行。

此外,由于 os.plock() 的行为可能因操作系统而异,并且不是所有操作系统都支持此功能,因此在编写依赖于它的代码时应该格外小心。在编写跨平台的代码时,可能需要使用其他机制来实现文件锁定,例如使用文件锁(file locking)机制,或者依赖于特定于平台的API。

os.popen(cmd, mode=‘r’, buffering=-1)

os.popen(cmd, mode=‘r’, buffering=-1) 是 Python 中 os 模块的一个函数,它用于从一个子进程执行一个 shell 命令,并返回一个文件对象,你可以通过这个文件对象来读取命令的输出或向其写入输入。这个函数提供了一个方便的方法来执行外部命令并与之交互。

参数说明:

  • cmd:要执行的 shell 命令,作为一个字符串传递。
  • mode:可选参数,指定文件对象的模式。默认为 ‘r’,表示读取命令的输出。如果设置为 ‘w’,则可以向命令写入输入。
  • buffering:可选参数,指定缓冲策略。默认为 -1,表示使用系统默认的缓冲策略。也可以设置为 0 表示无缓冲,或者一个正整数指定缓冲大小。

os.popen() 函数返回一个类似于文件对象的 Popen 对象,你可以使用 read()、readline()、readlines() 等方法来读取命令的输出,或者使用 write() 方法向命令写入输入。

下面是一个简单的示例,演示如何使用 os.popen() 来执行一个 shell 命令并读取其输出:

import os

# 执行 ls 命令并读取输出
with os.popen('ls') as f:
    output = f.read()
    print(output)

# 执行一个需要输入的命令,例如 cat 命令,并写入输入
with os.popen('cat', 'w') as f:
    f.write('Hello, world!\n')
    f.close()  # 必须关闭文件对象以确保所有数据都被写入

# 注意:上述 cat 命令示例可能不会按预期工作,因为当你写入数据后,cat 命令可能立即退出,
# 你可能看不到输出。为了看到输出,你可能需要重定向 cat 命令的输出到一个文件或其他地方。

请注意,os.popen() 在某些情况下可能不是执行外部命令的最佳选择。例如,它不支持直接获取命令的退出状态码,而且可能不如使用 subprocess 模块灵活和强大。subprocess 模块提供了更全面的功能来启动和管理子进程,包括错误处理、输入/输出重定向和进程通信等。如果你需要更复杂的控制或需要更详细的错误信息,建议考虑使用 subprocess 模块。

os.posix_spawn(path, argv, env, *, file_actions=None, setpgroup=None, resetids=False, setsid=False, setsigmask=(), setsigdef=(), scheduler=None)

os.posix_spawn() 是 Python 的一个底层操作系统接口,用于创建新的进程。这个函数提供了一种更加灵活和强大的方式来创建子进程,比使用 os.fork() 和 os.exec() 组合更为高效。

以下是 os.posix_spawn() 函数的参数解释:

  • path: 要执行的程序的路径。
  • argv: 一个列表,表示要传递给新进程的参数。argv[0] 通常是程序的名称,argv[1:] 是传递给程序的参数。
  • env: 一个字典,表示新进程的环境变量。

以下参数是可选的:

  • file_actions: 一个可选的文件操作列表,这些操作将在新进程开始执行之前和之后执行。这可以包括打开文件、关闭文件、重定向文件描述符等。
  • setpgroup: 如果设置为 True,则新进程将成为其进程组的新领导。如果是一个正整数,则新进程将加入该进程组,并成为其领导。
  • resetids: 如果设置为 True,则在新进程中重置其用户ID、组ID和进程组ID。
  • setsid: 如果设置为 True,则新进程将创建一个新的会话。
  • setsigmask: 一个信号掩码元组,表示在新进程中要阻塞的信号。
  • setsigdef: 一个信号到处理程序的映射,表示在新进程中要设置的信号处理程序。
  • scheduler: 如果指定,则设置新进程的调度策略。

这个函数的返回值是一个整数,表示新进程的进程ID,或者在出现错误时返回 -1 并设置 errno。

请注意,os.posix_spawn() 在所有平台上可能并不可用。特别是在 Windows 上,这个函数是不可用的。在使用它之前,建议检查其可用性。

os.posix_spawnp(path, argv, env, *, file_actions=None, setpgroup=None, resetids=False, setsid=False, setsigmask=(), setsigdef=(), scheduler=None)

os.posix_spawnp() 是 Python 的另一个用于创建新进程的函数,它与 os.posix_spawn() 类似,但有一个关键的区别:os.posix_spawnp() 会使用 PATH 环境变量来查找要执行的程序。这意味着你可以直接传递程序的名称(而不是完整的路径)作为 path 参数,系统会在 PATH 中查找该程序。

以下是 os.posix_spawnp() 函数的参数解释:

  • path: 要执行的程序的名称。由于该函数会使用 PATH 环境变量来查找程序,因此不需要提供完整的路径。
  • argv: 一个列表,表示要传递给新进程的参数。argv[0] 通常是程序的名称,argv[1:] 是传递给程序的参数。
  • env: 一个字典,表示新进程的环境变量。

其余的参数与 os.posix_spawn() 相同:

  • file_actions: 可选的文件操作列表。
  • setpgroup: 控制新进程的进程组设置。
  • resetids: 是否重置新进程的用户ID、组ID和进程组ID。
  • setsid: 是否创建新的会话。
  • setsigmask: 设置新进程中要阻塞的信号。
  • setsigdef: 设置新进程中的信号处理程序。
  • scheduler: 设置新进程的调度策略(如果支持的话)。

返回值和错误处理与 os.posix_spawn() 相同:成功时返回新进程的进程ID,失败时返回 -1 并设置 errno。

请注意,由于 os.posix_spawnp() 依赖于 PATH 环境变量来查找程序,因此如果 PATH 没有正确设置,或者程序不在 PATH 中,该函数将失败。此外,和 os.posix_spawn() 一样,os.posix_spawnp() 在所有平台上可能并不可用,特别是在 Windows 上。在使用之前,建议检查其可用性。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

熊猫Devin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值