【问题标题】:What happens when os.system() is executed in python thread?在 python 线程中执行 os.system() 会发生什么?
【发布时间】:2019-11-05 20:10:54
【问题描述】:

我是 python 线程的新手。我试图了解从 python 线程调用 os.system() 时会发生什么。我知道线程确实共享文件描述符、堆、代码和全局变量。我还读到 os.system(cmd) 创建了一个新的子外壳,并在那里执行提供的 cmd。

我的问题是,当 python 线程调用 os.system(cmd) 并且 cmd 执行“./test.exe input_file.dat”时,./test.exe 的进程是否共享任何内容(即输入文件、地址空间,堆等)与python线程?换句话说, os.system(cmd) 是否创建了一个与调用者进程或线程无关的新进程?

下面,我提供了我写的python代码。

#!/usr/bin/python

import threading
import os

semaphore = threading.Semaphore(3)

def run_command(cmd):
    with semaphore:
        os.system(cmd)

for i in range(3):
    threading.Thread(target=run_command, args=("./test.exe input_file.dat", )).start()

【问题讨论】:

    标签: python linux multithreading system-calls


    【解决方案1】:

    在python线程中执行os.system()会发生什么?

    • 创建了一个线程。这个线程——和所有线程一样——与创建它的线程共享它的地址空间。

    • 该线程调用fork() 来创建一个几乎与其自身完全相同的新子进程。子进程中只存在调用fork() 的线程;不复制其他线程。子进程与父进程有一个单独的地址空间,但内存映射到所有相同的地址。

      (这个子进程只存在很短的时间——除非你在调试器中采取特定步骤来暂停这里的进程,否则你不会在这种状态下看到它。Using threads in conjunction with fork() is generally inadvisable,但在这种情况下,它主要是好的。)

    • 新的子进程调用execve() 以将其自身完全替换为运行test.exe 的新进程。子进程的地址空间被销毁,并为新进程的镜像创建一个新的。

    • 同时,调用fork() 的线程现在调用waitpid()(或可能wait())来暂停其执行,直到新进程完成。一旦发生这种情况,os.system() 就会返回。

    【讨论】:

    • 非常感谢duskwuff 的详细解释。 “子进程与父进程有一个单独的地址空间,但内存映射在所有相同的地址”这行真的让我兴奋。我将对此进行深入研究。
    【解决方案2】:

    我找到了答案。当我们从 Python 线程 T1 执行 os.system(cmd) 时,新的子 shell 被创建为 T1 的子进程。因此,test.exe 共享 T1 的地址空间(基本上是 T1 的父 Python 代码的地址空间)。在 Linux 上使用 pmap,我的答案可以得到验证。

    Here I provide the pmap output for the parent process

    Here I provide the pmap output for the subprocess (test.exe)

    【讨论】:

    • 子进程与其父进程共享地址空间。这正是线程与进程的区别!
    • 您好,duskwuff,由于我是 python 线程的新手,需要您的帮助以了解我的答案有什么问题。当我执行上面提供的 python 代码并使用 Linux 的 pmap 命令时,它显示父进程(Python 代码)和 ./test.exe 的子进程映射在同一个地址空间上。那么,你能告诉我我是否在 pmap 命令输出中犯了任何错误吗?
    • 两个进程的内存映射到同一个地址这一事实并不意味着它们“共享地址空间”。尝试比较另一个不相关的过程;您可能会发现 everything 默认使用这些地址。
    猜你喜欢
    • 1970-01-01
    • 2017-11-18
    • 2017-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-31
    • 2017-08-19
    相关资源
    最近更新 更多