在Linux下运行的Julia程序中,当调整控制台窗口的大小时,我需要启动专门的操作。那么在Julia中,我怎样才能截获系统信号SIGWINCH(调整窗口大小)并附加执行所需 Action 的功能呢?
在Ada中,声明它非常简单:
protected Signalhandler is
procedure Handlewindowresizing;
pragma Attach_Handler (Handlewindowresizing, SIGWINCH);
end Signalhandler;
基于方案思想的解决方案:我尝试使用C库进行SIGWINCH中断监视。
myLibrary.h
void Winresize (void Sig_Handler());
myLibrary.c
#include "myLibrary.h"
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
void Winresize(void sig_handler (void)) {
signal(SIGWINCH, sig_handler);
}
编译与图书馆准备
gcc -c -Wall -fPIC myLibrary.c
gcc -shared -fPIC -o myLibrary.so myLibrary.o
Julia中使用C库的程序:
function getc1()
ret = ccall(:jl_tty_set_mode, Int32, (Ptr{Cvoid},Int32), stdin.handle, true)
ret == 0 || error("unable to switch to raw mode")
c = read(stdin, UInt8)
ccall(:jl_tty_set_mode, Int32, (Ptr{Cvoid},Int32), stdin.handle, false)
c
end
function traitement() println(displaysize(stdout)); end
Mon_traitement_c = @cfunction(traitement, Cvoid, ())
ccall((:Winresize, "/home/Emile/programmation/Julia/myLibrary.so"), Cvoid, (Ptr{Cvoid},), Mon_traitement_c)
while true
println(getc1())
end
Julia程序正常运行,但是在调整终端窗口的大小时,会发出段错误(核心转储),并说程序已退出,代码为139。
那么问题是这种分割错误是从哪里来的呢?从编译模型? Julia (Julia)无权在C负责信号监控的存储部分中控制代码执行?
在Sig_handler中删除println操作可抑制段错误:
curr_size = displaysize(stdout)
new_size = curr_size
function traitement() global new_size ; new_size = displaysize(stdout); return end
Mon_traitement_c = @cfunction(traitement, Cvoid, ())
ccall((:Winresize, "/home/Emile/programmation/Julia/myLibrary.so"), Cvoid, (Ptr{Cvoid},), Mon_traitement_c)
while true
global curr_size, new_size
if new_size != curr_size
curr_size = new_size
println(curr_size)
end
sleep(0.1)
end
最佳答案
由于到目前为止还没有人回答这个问题,因此一种可能的解决方法是在某些时间间隔中异步监视终端的大小。
function monitor_term(func)
@async begin
curr_size = displaysize(stdout)
while (true)
sleep(0.1)
new_size = displaysize(stdout)
if new_size != curr_size
curr_size = new_size
func()
end
end
end
end
现在示例用法:
julia> monitor_term(() -> print("BOO!"))
Task (runnable) @0x0000000013071710
只要终端处于事件状态,对其大小的任何更改都将打印
BOO!
。
关于julia - Julia中的系统信号拦截,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60806139/