跳转至

多进程与多线程

在Python中,threading.Thread类用于创建新线程,而线程的daemon属性决定了该线程是否是守护线程。具体来说,daemon=Truedaemon=False的作用如下:

1. daemon=True(守护线程)

  • 如果设置为True,该线程被标记为守护线程。

  • 守护线程是指在主程序结束时,所有守护线程会自动被杀死,不会影响程序的退出。

  • 也就是说,主程序退出时,如果还有守护线程在运行,主程序会不等守护线程完成就直接退出。这通常用于那些不影响程序最终退出的后台任务。

  • 守护线程适用于某些任务,例如:日志记录、监控、定时任务等,它们在主程序结束时可以被终止。

示例:

import threading
import time

def background_task():
  while True:
      print("Running background task")
      time.sleep(1)

t = threading.Thread(target=background_task)
t.daemon = True  # 设置为守护线程
t.start()

print("Main program ends.")
# 主程序退出时,背景任务线程也会被停止

2. daemon=False(非守护线程,默认)

  • 默认情况下,线程的daemon属性是False

  • 非守护线程会阻塞主程序的退出。也就是说,主程序会等待所有非守护线程完成后才退出。

  • 如果有非守护线程正在运行,主程序不会退出,直到这些线程执行完毕。

示例:

import threading
import time

def background_task():
  print("Starting background task")
  time.sleep(5)
  print("Background task finished")

t = threading.Thread(target=background_task)
t.daemon = False  # 默认是False,即非守护线程
t.start()

print("Main program ends.")
# 主程序会等待背景任务完成后才退出

总结:

  • daemon=True:主程序退出时,守护线程会被强制结束。
  • daemon=False:主程序会等待非守护线程执行完毕后退出,通常用于需要确保线程完成任务的情况。

使用multiprocessing时, 一个py文件中,

需要先调用freeze_support

multiprocessing.freeze_support() # windows创建的子进程不是linux的fork, 所以需要这个

然后才能调用multiprocessing的其他功能

multiprocessing.Manager().list()

并且multiprocessing.Manager().list()需要放到一个函数中, 或者放到另外一个文件中

import multiprocessing
multiprocessing.freeze_support()
# ...
def main():
    multiprocessing.Manager().list()
    #...
if __name__ == "__main__":
    main()

否则会遇到这样的提示

        An attempt has been made to start a new process before the
        current process has finished its bootstrapping phase.

        This probably means that you are not using fork to start your
        child processes and you have forgotten to use the proper idiom
        in the main module:

            if __name__ == '__main__':
                freeze_support()
                ...

        The "freeze_support()" line can be omitted if the program
        is not going to be frozen to produce an executable.