【问题标题】:Spawning threads in newly spawned processes and using print to view thread state in Python在新生成的进程中生成线程并使用 print 在 Python 中查看线程状态
【发布时间】:2021-11-29 08:12:53
【问题描述】:

我有一个创建 2 个新进程的 python 脚本。然后,在每个新进程中,我创建 3 个线程。

import os
import threading
import multiprocessing as mp
import time


def extra_threads():
    x = 7
    while x != 0:
        x -= 1
        for specific_thread in threading.enumerate():
            print('THREAD:', specific_thread, f'X Value: {x},', os.getpid())


def new_process():
    print('PROCESS: New Process PID:', os.getpid())
    print('PROCESS: Thread Count:',
          threading.active_count())
    for specific_thread in threading.enumerate(): 
        print('PROCESS:', specific_thread)
    print('PROCESS: CREATING 3 ADDITIONAL THREADS IN PID:', os.getpid())

    for y in range(3):
        t = threading.Thread(target=extra_threads)
        t.setDaemon(True)
        t.start()

    print('PROCESS: Thread Count: ', threading.active_count(), 'PID:', os.getpid())

    while True:
        pass


if __name__ == '__main__':
    # display information about this process
    print('Parent Process ID: ', os.getpid())  # Get's the unique Process ID of this process
    print('Parent Thread Count: ', threading.active_count())  # Shows that it is initially 1 thread to his process

    for thread in threading.enumerate():
        print('MAIN PROGRAM THREADS:', thread)  # Prints information about each of those threads

    print('\nSTARTING 2 NEW PROCESSES...')
    print()
    for z in range(2):
        print(f'Starting {z + 1} New Process...')
        print()
        mp.Process(target=new_process).start()
        time.sleep(1)
        print()

当我查看终端的进程时,输出符合预期。 我有 2 个进程 (ps -eF) 和每个进程的 3 个线程(当我运行 ps -L 时)。

但是,对于每个进程中的每个线程,打印语句(在 extra_thread() 函数中)在终端出现两次。这可以通过重复多次打印的 X 值来观察。

有人能解释为什么会这样吗?

THREAD: <_MainThread(MainThread, started 140020333217600)> X Value: 6, 449
**THREAD: <Thread(Thread-1, started daemon 140020326205184)> X Value: 6, 449**
THREAD: <_MainThread(MainThread, started 140020333217600)> X Value: 6, 449
THREAD: <_MainThread(MainThread, started 140020333217600)> X Value: 5, 449
THREAD: <_MainThread(MainThread, started 140020333217600)> X Value: 6, 449
**THREAD: <Thread(Thread-1, started daemon 140020326205184)> X Value: 6, 449
THREAD: <Thread(Thread-1, started daemon 140020326205184)> X Value: 6, 449**
THREAD: <Thread(Thread-2, started daemon 140020317751040)> X Value: 6, 449
THREAD: <Thread(Thread-1, started daemon 140020326205184)> X Value: 5, 449
THREAD: <Thread(Thread-3, started daemon 140020309296896)> X Value: 6, 449
THREAD: <Thread(Thread-2, started daemon 140020317751040)> X Value: 5, 449
THREAD: <_MainThread(MainThread, started 140020333217600)> X Value: 5, 449
THREAD: <Thread(Thread-1, started daemon 140020326205184)> X Value: 5, 449
THREAD: <Thread(Thread-3, started daemon 140020309296896)> X Value: 5, 449
THREAD: <_MainThread(MainThread, started 140020333217600)> X Value: 4, 449
THREAD: <Thread(Thread-2, started daemon 140020317751040)> X Value: 5, 449
THREAD: <Thread(Thread-1, started daemon 140020326205184)> X Value: 4, 449
THREAD: <Thread(Thread-3, started daemon 140020309296896)> X Value: 5, 449
THREAD: <Thread(Thread-2, started daemon 140020317751040)> X Value: 4, 449
THREAD: <_MainThread(MainThread, started 140020333217600)> X Value: 4, 449
THREAD: <Thread(Thread-3, started daemon 140020309296896)> X Value: 4, 449
THREAD: <Thread(Thread-1, started daemon 140020326205184)> X Value: 4, 449
THREAD: <_MainThread(MainThread, started 140020333217600)> X Value: 3, 449
THREAD: <Thread(Thread-1, started daemon 140020326205184)> X Value: 3, 449
...

THREAD: <Thread(Thread-1, started daemon 140020326205184)> X Value: 5, 450
THREAD: <Thread(Thread-3, started daemon 140020309296896)> X Value: 5, 450
THREAD: <Thread(Thread-2, started daemon 140020317751040)> X Value: 5, 450
THREAD: <Thread(Thread-1, started daemon 140020326205184)> X Value: 4, 450
THREAD: <Thread(Thread-3, started daemon 140020309296896)> X Value: 5, 450
THREAD: <Thread(Thread-2, started daemon 140020317751040)> X Value: 4, 450
THREAD: <Thread(Thread-3, started daemon 140020309296896)> X Value: 4, 450
THREAD: <Thread(Thread-1, started daemon 140020326205184)> X Value: 4, 450
THREAD: <Thread(Thread-1, started daemon 140020326205184)> X Value: 3, 450

是不是因为在新进程线程中调用了print语句(打印“there”也打印在父进程中?

另外,线程信息中“started daemon”后面的数字是多少?如果是内存地址,为什么跨不同进程的子线程都一样? (主线程地址与生成的所有 2 个进程不同,这是意料之中的)。

谢谢!

【问题讨论】:

    标签: python linux multithreading multiprocessing


    【解决方案1】:

    您的日志与我预期的一样。请记住,每个线程都将打印每个循环中所有线程的完整清单。因此,我希望每个进程看到 28 个日志条目(4 个线程 x 7 次迭代)。

    数字是进程本地的“线程标识符”。如果您在 LInux 上,这三个进程都是彼此的精确副本,因此执行相同的代码将始终以相同的地址结束。

    【讨论】:

    • 同意。我确实希望有 28 个日志条目。但是,出于某种原因,我得到了 56。我的期望是不会在唯一 PID 中看到每个唯一线程的重复 X 值。
    • 感谢您解释线程标识符。这部分现在很清楚了。
    • 每个进程得到 56 个?从您显示的输出中不清楚。每个线程 id/进程 id/x 组合似乎都是唯一的。
    • 例如,如果您查看输出的顶部,PID 449,Thread-1,您会看到甚至有 3 行 X 值 = 6。(第 2 行,第 6 行,第 7 行).. 或第 1 行、第 5 行、第 6 行(如果索引从 0 开始)。
    • 请记住,您正在打印的“x”不是日志行中显示的线程的“x”。它是正在盘点的线程的“x”。线程 1 将打印每个线程的值 6。线程 2 将打印每个线程的值 6。线程 3 将打印每个线程的值 6。
    猜你喜欢
    • 1970-01-01
    • 2019-04-10
    • 2012-01-20
    • 2015-01-11
    • 1970-01-01
    • 1970-01-01
    • 2015-06-23
    • 2021-09-18
    • 1970-01-01
    相关资源
    最近更新 更多