Julia의 시스템 신호 차단


9

Linux에서 실행되는 Julia 프로그램에서는 콘솔 창의 크기를 조정할 때 전용 작업을 시작해야합니다. 어떻게 Julia에서 시스템 신호 SIGWINCH (창 크기 조정)를 가로 채서 필요한 조치를 수행하는 함수를 첨부 할 수 있습니까?

Ada에서는 그것을 선언하는 것이 다소 간단합니다.

 protected Signalhandler is
      procedure Handlewindowresizing;
      pragma Attach_Handler (Handlewindowresizing, SIGWINCH);
 end Signalhandler;

SCHEMER의 아이디어에 기반한 임시 솔루션 : SIGWINCH 중단 모니터링을 수행하는 C 라이브러리를 사용하려고합니다.

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-벽 -fPIC myLibrary.c

gcc -shared -fPIC -o myLibrary.so myLibrary.o

C-Library를 사용하는 Julia의 프로그램 :

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

답변:


4

지금까지 아무도이 질문에 대답하지 않았으므로 가능한 해결 방법 중 하나가 일정 시간 간격으로 터미널 크기를 비동기 적으로 모니터링 할 수 있습니다.

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!됩니다.


현재 콘솔 창 크기를 얻는 좋은 방법을 몰랐습니다. displaysize (stdout) 감사합니다
Emile

0

예, 그것은 약속으로 가득 찬 새로운 언어에서 거의 기대하지 않는 대체 솔루션입니다 ...하지만 아구창이 없기 때문에 실제로 검은 새를 먹을 수 있습니다 (미소).

그러나 Julia가 Unix / Linux 세계의 시스템 신호를 고려할 계획이 없다면 signal.h가 액세스하는 것과 같은 C 라이브러리를 사용하여이를 수행 할 수 있습니다.

 #include <stdio.h>
 #include <stdlib.h>
 #include <signal.h>

 void sig_handler(int signum)
 {
    printf("Received signal %d\n", signum);
 }

int main()
{
   signal(SIGINT, sig_handler);
   sleep(10); // This is your chance to press CTRL-C
   return 0;
}

시스템 신호가 수신 될 때 예상되는 작업을 수행하는 julia 함수를 정의해야합니다. C에서 Sig_handler로 사용 가능하게하고 julia로부터 C 명령문 신호 (SIGWINCH, Sig_handler)를 호출하십시오.

정확한 코드를 작성하기 위해 julia에 익숙하지 않습니다. 그러나 이것은 아이디어입니다 ...


나는 당신이 제안한 것을 구현하려고 노력할 것입니다.
Emile

@Emile (Jullia 's 작성 포함)을 구현 ccal하고 나중에 표준 Julia 패키지로 만들고 싶다면 포장에 도움을 줄 수 있습니다.
Przemyslaw Szufel

정식 주목 ! 줄리아 문서에서 조금 더 나아가 야합니다.
Emile

@Przemyslaw Szufel : 위의 세그먼테이션 결함에 대한 나의 질문에 대한 보완으로 C 함수를 사용하여 인터럽트를 잡을 때 발생하는 분석은 무엇입니까?
Emile

Julia-C 통합 코드를 작성하지 않았습니다. 그러나 Julia 스레드에서 시스템 IO를 사용할 때마다 segfault 오류가 매우 오랫동안 발생했기 때문에 문제가있을 수 있습니다. 아마도 첫 번째 단계에서 터미널 크기를 묻지 않고 println ( "boo")을 출력했을 때 무슨 일이 있었는지 알아보십시오.
Przemyslaw Szufel
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.