gpt4 book ai didi

python - Python中的可中断线程连接

转载 作者:IT老高 更新时间:2023-10-28 20:28:37 25 4
gpt4 key购买 nike

有什么办法可以等待线程终止,但仍然拦截信号?

考虑以下 C 程序:

#include <signal.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>

void* server_thread(void* dummy) {
sleep(10);
printf("Served\n");
return NULL;
}

void* kill_thread(void* dummy) {
sleep(1); // Let the main thread join
printf("Killing\n");
kill(getpid(), SIGUSR1);
return NULL;
}

void handler(int signum) {
printf("Handling %d\n", signum);
exit(42);
}

int main() {
pthread_t servth;
pthread_t killth;

signal(SIGUSR1, handler);

pthread_create(&servth, NULL, server_thread, NULL);
pthread_create(&killth, NULL, kill_thread, NULL);

pthread_join(servth, NULL);

printf("Main thread finished\n");
return 0;
}

它在一秒钟后结束并打印:

Killing
Handling 10

相比之下,这是我用 Python 编写它的尝试:

#!/usr/bin/env python
import signal, time, threading, os, sys

def handler(signum, frame):
print("Handling " + str(signum) + ", frame:" + str(frame))
exit(42)
signal.signal(signal.SIGUSR1, handler)

def server_thread():
time.sleep(10)
print("Served")
servth = threading.Thread(target=server_thread)
servth.start()

def kill_thread():
time.sleep(1) # Let the main thread join
print("Killing")
os.kill(os.getpid(), signal.SIGUSR1)
killth = threading.Thread(target=kill_thread)
killth.start()

servth.join()

print("Main thread finished")

打印出来:

Killing
Served
Handling 10, frame:<frame object at 0x12649c0>

如何让它表现得像 C 版本?

最佳答案

鉴于全局解释器锁,Python 中的线程有点奇怪。如果不求助于 eliben 建议的加入超时和 isAlive,您可能无法实现您想要的。

文档中有两个地方给出了这个原因(可能还有更多)。

第一个:

来自 http://docs.python.org/library/signal.html#module-signal :

Some care must be taken if both signals and threads are used in the same program. The fundamental thing to remember in using signals and threads simultaneously is: always perform signal() operations in the main thread of execution. Any thread can perform an alarm(), getsignal(), pause(), setitimer() or getitimer(); only the main thread can set a new signal handler, and the main thread will be the only one to receive signals (this is enforced by the Python signal module, even if the underlying thread implementation supports sending signals to individual threads). This means that signals can’t be used as a means of inter-thread communication. Use locks instead.

第二个,来自 http://docs.python.org/library/thread.html#module-thread :

Threads interact strangely with interrupts: the KeyboardInterrupt exception will be received by an arbitrary thread. (When the signal module is available, interrupts always go to the main thread.)

编辑: 在此处的 python 错误跟踪器上对此机制进行了不错的讨论:http://bugs.python.org/issue1167930 .当然,它的结尾是 Guido 说:“这不太可能消失,所以你只需要活着有了这个。正如您所发现的,指定超时可以解决问题(有点)。” YMMV :-)

关于python - Python中的可中断线程连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/631441/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com