Python-守护程序线程是否在主线程之后完成?

时间:2019-04-02 19:55:03

标签: python-2.7 daemon python-multithreading

当守护程序= True时,通过Thread删除并替换Windows Service。应该行吗?!

不到一年前,我使用Python 2.7py2exe和另一个exe制作了Windows Service exe,并将其作为线程触发 从该服务中将其替换为新服务。程序效果很好! 同时,我读了很多有关Python Threadnig的文章,但现在我不明白什么是正确的,或者为什么它根本不起作用?!

  1. s_service.exe作为Windows服务安装并启动。这行得通。
  2. 另一个文件:w_update.exes_service.exe位于同一个目录中。
  3. “下载”目录中的另一个s_service.exe(称为s_service.exe v2.0):
[ProjectPy]
    [Download]
        s_service.exe
    s_service.exe   <--- This one is active as Windows Service
    w_update.exe

关于服务:

为简便起见,我们假设s_service.exe只有一项任务-每30秒将w_update.exe作为守护程序运行。

if (time_is_right):
    t = threading.Thread(target=run_exe, args=["w_update.exe"])
    t.daemon = True # <--------- SEE THIS!
    t.start()

def run_exe(tool):
    proggie = os.path.join(some_path, tool)
    if os.path.exists(proggie):
        process = subprocess.Popen(proggie, stdout=subprocess.PIPE, shell=False, creationflags=0x08000000)
        process.wait()

关于更新程序:

Updater按此顺序执行以下操作:

1. Stop the service s_service.exe
2. Wait 5 sec
3. Remove service from Windows
4. Wait 5 sec
5. Move ProjectPy\Download\s_service.exe to ProjectPy\s_service.exe (overwrites old s_service.exe v1.0 with new s_service.exe v2.0)
6. Install service s_service.exe to Windows
7. Wait 5 sec
8. Start service

(下面是代码摘录,省略了控制结构)

service_name = "MyPythonService"

print("Stop Service...")
win32serviceutil.StopService(service_name)
time.sleep(5)

print("Remove Service...")
win32serviceutil.RemoveService(service_name)
time.sleep(5)

print("Move: ", download_dir_filename, current_dir_filename)
shutil.move(download_dir_filename, current_dir_filename)

print("Install Service")
win32serviceutil.InstallService(None, service_name, "My Python Service Display Name", startType=win32service.SERVICE_AUTO_START, exeName=current_dir_filename, description=service_description)
time.sleep(5)

print("Start Service")
win32serviceutil.StartService(service_name)

我的问题是:为什么行得通?!

来自各种资源:

  1. 可以将线程标记为“守护程序线程”。该标志的含义是整个Python程序在仅保留守护程序线程时退出

  2. 设置thread.daemon = True将允许主程序退出。 应用程序通常要等到所有子线程完成后再

  3. 非守护程序线程在主程序未死亡时会阻止其退出。守护程序线程在运行时不会阻止主程序退出。并且当主程序退出时,关联的守护程序线程也会被杀死

  4. 守护线程的要点是它在主线程关闭时继续运行

  5. 守护程序线程不会阻止主线程退出并继续在后台运行

  6. 堆栈溢出问题:尽管主程序完成了,后台驻留程序线程仍未退出

  7. https://www.youtube.com/watch?v=OKedlEeBxU8-“ 当主程序终止时,守护线程也将终止

  8. 守护程序线程是即使脚本的其余部分已停止,仍将继续运行的线程。这意味着将线程守护程序设置为true意味着它将在主线程完成(或退出)后继续运行

a)有人说,当主线程完成时,守护程序线程也会终止。

如果这是真的,我的守护线程w_update.exe应该在步骤1. Stop the service s_service.exe之后或步骤3. Remove service from Windows之后被杀死 并且无法继续执行步骤5、6和8。 但是它正确地(重新)安装并(重新)启动(新)服务-全部8个步骤。

b)有人说即使脚本的其余部分已经停止,该线程也将继续运行。

这是我的情况。

其他信息:由于存在错误,一旦我在MS Windows Server 2008上遇到问题:

  1. 任务管理器中一个s_service.exe的实例,

  2. 超过350个w_update.exe实例(以及所有其他守护程序线程实例)

当我停止s_service.exe时,所有w_update.exe实例(以及所有其他守护线程实例)都被自动删除。 因此这有利于a)有人说,当主线程完成时-守护程序线程也会终止。

我是否缺少某些内容,或者Python版本之间或Windows OS-es之间的行为是否有所不同? 我很困惑...

0 个答案:

没有答案