为什么Python';s Event.wait()是否会被某些系统上的信号而不是其他系统上的信号中断?

为什么Python';s Event.wait()是否会被某些系统上的信号而不是其他系统上的信号中断?,python,signals,Python,Signals,考虑以下Python脚本: from datetime import datetime from threading import Event event = Event() start = datetime.now() try: event.wait(5) except KeyboardInterrupt: print("caught Ctrl+C after %s" % (datetime.now() - start)) 当我在Debian上运行它(特别是Docker的

考虑以下Python脚本:

from datetime import datetime
from threading import Event

event = Event()
start = datetime.now()

try:
    event.wait(5)
except KeyboardInterrupt:
    print("caught Ctrl+C after %s" % (datetime.now() - start))
当我在Debian上运行它(特别是Docker的python:3.6.5-stretch)并快速按下Ctrl+C时,它会立即中断:

# python mptest.py
^Ccaught Ctrl+C after 0:00:00.684854
# 
但当我在Alpine上运行它(具体来说,Docker的python:3.6.5-alpine3.7)并快速按下Ctrl+C时,整个等待过程就会结束:

/ # python mptest.py 
^Ccaught Ctrl+C after 0:00:05.000314
/ # 

造成这种差异的原因是什么?其中一个系统不正确吗?

短版本:

Python假设如果信号在等待时中断,
sem\u timedwait
将返回
EINTR
。Glibc(Debian的libc)做到了这一点,但POSIX说这样做是可选的,而musl(Alpine的libc)则没有做到

长版本:

Python的
事件
是内部的,它本身就是。以下程序出于相同的原因显示了相同的行为,仅使用了

from datetime import datetime
from threading import Lock

lock = Lock()
lock.acquire()
start = datetime.now()

try:
    lock.acquire(True, 5)
except KeyboardInterrupt:
    print("caught Ctrl+C after %s" % (datetime.now() - start))
发件人:

锁获取现在可以被POSIX上的信号中断

假设这段文档是正确的,这意味着Debian上的行为是正确的,而Alpine上的行为是不正确的

Python的
acquire
是(假设它存在,它在Debian和Alpine上都存在。如果它不存在,它就会存在)

以下C程序演示了在每个系统上构建时,
sem_timedwait
的不一致性:

#包括
#包括
#包括
#包括
#包括
#包括
#包括
无效处理程序(int sig){
放入(“信号处理器”);
}
int main(){
struct-sigaction-sa;
sa.sa_handler=handler;
sigemptyset(和sa.sa_面具);
sa.sa_标志=0;
sigaction(SIGALRM,&sa,NULL);
警报(1);
结构timespects;
时钟获取时间(时钟实时,&ts);
ts.tv_sec+=2;
扫描电镜;
sem_init(&sem,0,0);
sem_timedwait(&sem,&ts);
如果(errno==EINTR){
puts(“被信号中断”);
}else if(errno==ETIMEDOUT){
卖出(“超时”);
}
返回0;
}
在Debian上,它在1秒后以“被信号中断”退出。在阿尔卑斯山,它在2秒后退出,并显示“超时”

sem_timedwait
是一个libc函数。特别是,它声明它“可能”因EINTR而失败,而不是“应该”。这意味着glibc(Debian's)和musl(Alpine's)都不正确

对,穆尔

在我看来,这里的错误在于Python依赖POSIX的可选特性。事实证明,Python以前曾被攻击过,因为信号量不存在,它使用了
pthread\u cond\u timedwait
。此外,此问题还会导致在针对musl构建时失败。我打开了这个