julia - Julia中的系统信号拦截

标签 julia signals ada

在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/

相关文章:

ios - 我可以在 Swift 应用程序中引用 Ada 库吗?

julia - 基于列的反向替换函数的数学失败计数(Julia)

julia - 如何找到一个复矩阵 A 使得 A * Transpose(A) = B,其中 B = Transpose(B) 并且是复数?

c++ - 如何使用 C++ 以编程方式终止进程?

bash - `ulimit -t` 在 shell 和操作系统之间完全不可移植?

arrays - 将数组初始化为空对象

import - Ada:导入不等式运算符 "/="

julia - 如何在 Julia 中使用 for 循环定义 JuMP 变量?

julia - 如何在 Julia 中规范化矩阵的列

c++ - 在 C 中将参数/参数信号传递给 GTK+ 上的回调