在Linux下运行的Julia程序中,需要在调整控制台窗口大小时启动专用操作。那么在Julia中,我怎样才能截获系统信号SIGWINCH(调整窗口大小)并附加执行所需动作的功能呢?
在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)无权在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
1
使用ccall((:signal ...)和@cfunction将其实现为SignalHandlers.jl模块应该相当简单,但是AFAIK尚未完成
—
Bill
您的建议是一个好建议。谢谢。
—
埃米尔(Emile)