Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
什么是python线程_Python_Multithreading - Fatal编程技术网

什么是python线程

什么是python线程,python,multithreading,Python,Multithreading,关于Python线程,我有几个问题 Python线程是Python还是OS实现 当我使用htop时,多线程脚本有多个条目——相同的内存消耗,相同的命令,但不同的PID。这是否意味着[Python]线程实际上是一种特殊的进程?(我知道htop中有一个将这些线程显示为一个进程的设置-Hide userland threads) 说: 线程可以标记为“守护线程”。这一点的意义 标志是当只有守护进程线程时,整个Python程序退出 剩下的就剩下了 我的理解是:当所有非守护进程线程终止时,主线程终止 因此

关于Python线程,我有几个问题

  • Python线程是Python还是OS实现
  • 当我使用htop时,多线程脚本有多个条目——相同的内存消耗,相同的命令,但不同的PID。这是否意味着[Python]线程实际上是一种特殊的进程?(我知道htop中有一个将这些线程显示为一个进程的设置-
    Hide userland threads
  • 说:
  • 线程可以标记为“守护线程”。这一点的意义 标志是当只有守护进程线程时,整个Python程序退出 剩下的就剩下了

    我的理解是:当所有非守护进程线程终止时,主线程终止

    因此,如果“当只剩下守护进程线程时,整个python程序退出”,python守护进程线程就不是python程序的一部分了

  • Python线程在我所知道的所有实现(C Python、PyPy和Jython)中都是使用OS线程实现的。对于每个Python线程,都有一个底层OS线程

  • 某些操作系统(Linux就是其中之一)在所有运行进程的列表中显示由同一可执行文件启动的所有不同线程。这是操作系统的实现细节,而不是Python。在其他一些操作系统上,列出所有进程时可能看不到这些线程


  • 进程将在最后一个非守护进程线程完成时终止。此时,所有守护进程线程都将终止。因此,这些线程是进程的一部分,但不会阻止进程终止(而常规线程会阻止它)。这是用纯Python实现的。当调用系统
    \u exit
    函数时,进程终止(它将杀死所有线程),当主线程终止(或调用
    sys.exit
    时,Python解释器检查是否有另一个非守护进程线程在运行。如果没有,则调用
    \u exit
    ,否则等待非守护进程线程完成


  • 守护进程线程标志由
    threading
    模块在纯Python中实现。加载模块时,将创建一个
    Thread
    对象来表示主线程,它的
    \u exitfunc
    方法将注册为
    atexit
    钩子

    此功能的代码为:

    class _MainThread(Thread):
    
        def _exitfunc(self):
            self._Thread__stop()
            t = _pickSomeNonDaemonThread()
            if t:
                if __debug__:
                    self._note("%s: waiting for other threads", self)
            while t:
                t.join()
                t = _pickSomeNonDaemonThread()
            if __debug__:
                self._note("%s: exiting", self)
            self._Thread__delete()
    
    调用
    sys.exit
    或主线程终止时,Python解释器将调用此函数。当函数返回时,解释器将调用系统退出函数。当只有守护进程线程在运行时(如果有的话),函数将终止

    调用
    \u exit
    函数时,操作系统将终止所有进程线程,然后终止进程。在完成所有非守护进程线程之前,Python运行时不会调用
    \u exit
    函数

    所有线程都是进程的一部分


    我的理解是:当所有 非守护进程线程被终止

    因此,如果“整个 Python程序在只剩下守护进程线程时退出“

    你的理解是错误的。对于操作系统来说,一个进程由许多线程组成,所有线程都是相等的(对于操作系统来说,主线程没有什么特别之处,只是C运行时在
    函数的末尾添加了对
    \u exit
    的调用)。而且操作系统不知道守护进程线程。这纯粹是一个Python概念

    Python解释器使用本机线程来实现Python线程,但必须记住创建的线程列表。并使用其
    atexit
    钩子,确保
    \u exit
    函数仅在最后一个非守护进程线程终止时返回操作系统。当使用“整个Python程序”时,文档涉及整个过程


    以下程序有助于理解守护进程线程和常规线程之间的区别:

    import sys
    import time
    import threading
    
    class WorkerThread(threading.Thread):
    
        def run(self):
            while True:
                print 'Working hard'
                time.sleep(0.5)
    
    def main(args):
        use_daemon = False
        for arg in args:
            if arg == '--use_daemon':
                use_daemon = True
        worker = WorkerThread()
        worker.setDaemon(use_daemon)
        worker.start()
        time.sleep(1)
        sys.exit(0)
    
    if __name__ == '__main__':
        main(sys.argv[1:])
    
    如果使用“--use_daemon”执行此程序,您将看到该程序将只打印少量努力工作的
    行。如果没有此标志,即使主线程完成,程序也不会终止,并且程序将打印
    努力工作
    行,直到终止

  • Python线程实际上是一种解释器实现,因为所谓的全局解释器锁(GIL),即使在技术上使用os级线程机制。在*nix上,它利用了pthreads,但GIL有效地使其成为与应用程序级线程范例的混合。因此,您将在ps/top输出中多次在*nix系统上看到它,但它的行为(性能方面)仍类似于软件实现的线程

  • 不,您只是看到了操作系统的底层线程实现。这种行为是由*nix pthread-like-threading或im公开的,甚至windows也以这种方式实现线程

  • 当程序关闭时,它也会等待所有线程完成。如果您有线程,这可能会不确定地推迟退出,那么明智的做法是将这些线程标记为“守护进程”,并允许您的程序完成,即使这些线程仍在运行

  • 您可能会感兴趣的一些参考资料:


    我不熟悉实现,所以让我们做一个实验:

    import threading
    import time
    
    def target():
        while True:
            print 'Thread working...'
            time.sleep(5)
    
    NUM_THREADS = 5
    
    for i in range(NUM_THREADS):
        thread = threading.Thread(target=target)
        thread.start()
    
  • 使用
    ps-o cmd,nlwp
    报告的线程数是
    NUM_threads+1
    (主线程再多一个),因此只要操作系统工具检测到线程数,它们就应该是操作系统线程。我尝试了cpython和jython,尽管在jython中还有一些其他线程在运行,但对于我添加的每个额外线程,
    ps
    将线程数增加一个

  • 我不确定
    thread.daemon = True