我使用的是一个用go编写的python驱动程序,该驱动程序连接到某个服务并进行一些处理。我们发现服务的一个“unheanlthy”示例存在问题,导致驱动程序卡住,除非我们kill
进程,否则无法终止。
在做一些实验时,我发现当执行用go编写的扩展时,程序会忽略发出的Ctrl+C
命令,直到控制权回到Python,而C编写的扩展不会发生这种情况,在执行C代码时会引发KeyboardInterrupt
。我的问题是为什么会发生这种情况,如果有办法解决这个问题或发出一种超时。尝试使用threading.Timer
引发一个异常来模拟超时,但问题是该异常是在它自己的线程中抛出的,并且不会中断主线程。在Python(cpython)3.9
和3.10
中测试。至于我写的扩展,Go版本是1.20.4
,C编译器是9.4.0
。
我会在下面留一个小房间。
Python代码:
import ctypes
import ctypes
go_library = ctypes.cdll.LoadLibrary('./go_library.so')
hello_Go = go_library.helloWorld
c_library = ctypes.cdll.LoadLibrary("./c_library.so")
hello_c = c_library.helloWorld
try:
print("Calling golang code")
hello_Go()
print("Calling C code")
hello_c()
except KeyboardInterrupt:
print("Ctrl+C issued DD:")
finally:
print("Done")
围棋推广
package main
import (
"C"
"log"
"time"
)
func helloWorld(){
log.Println("Hello World")
time.Sleep(10 * time.Second)
log.Println("Done sleeping")
}
func main(){
}
C扩展
#include <stdio.h>
int helloWorld() {
printf("Hello from C\n");
sleep(10);
printf("Done sleeping from C\n");
return 0;
}
1条答案
按热度按时间zd287kbt1#
我遇到了同样的情况。经过一番研究,我找到了解决办法。
根据this answer:
Python在SIGINT上安装了一个信号处理程序,它只是设置一个由主解释器循环检查的标志。为了让这个处理程序正常工作,Python解释器必须运行Python代码。
看来在运行golang代码时,golang调用python安装了SIGINT信号处理程序来设置一个标志。因此,当运行回到python时,检测到KeyboardInterrupt。
来自Golang Doc:
(When调用Go代码的非Go程序)如果为异步信号调用Notify,则会为该信号安装Go信号处理程序。如果稍后为该信号调用Reset,则将重新安装该信号的原始处理,恢复非Go信号处理程序(如果有的话)。
因此,下面的代码将在go代码中捕获SIGINT,并在SIGINT时立即返回函数。