Dalam program Julia yang berjalan di Linux, saya harus meluncurkan tindakan khusus ketika jendela konsol diubah ukurannya. Jadi bagaimana di Julia, dapatkah saya mencegat sinyal sistem SIGWINCH (mengubah ukuran jendela) dan melampirkan padanya sebuah fungsi yang melakukan tindakan yang diperlukan?
Dalam Ada agak mudah untuk menyatakannya:
protected Signalhandler is
procedure Handlewindowresizing;
pragma Attach_Handler (Handlewindowresizing, SIGWINCH);
end Signalhandler;
SOLUSI TENTATIF BERDASARKAN IDEA OF SCHEMER: Saya mencoba menggunakan Perpustakaan C yang melakukan pemantauan gangguan 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);
}
Kompilasi & persiapan Perpustakaan
gcc -c -Wall -fPIC myLibrary.c
gcc -bagi -fPIC -o myLibrary.so myLibrary.o
Program di Julia yang menggunakan C-Library:
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
Program Julia berjalan dengan baik tetapi ketika jendela terminal diubah ukurannya kesalahan Segmentasi (core dumped) dikeluarkan dan program dikatakan keluar dengan kode: 139.
Jadi pertanyaannya adalah dari mana kesalahan segmentasi ini berasal? Dari model kompilasi? Julia tidak memiliki hak untuk mengontrol eksekusi kode di bagian memori di mana C mengelola pemantauan sinyal?
Menghapus operasi println di Sig_handler menekan kesalahan segmentasi:
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
Jawaban:
Karena tidak ada yang menjawab pertanyaan ini sejauh ini, satu solusi yang mungkin dapat secara asinkron memantau ukuran terminal dalam beberapa interval waktu.
Dan sekarang penggunaan sampel:
Selama terminal masih hidup, setiap perubahan ukurannya akan dicetak
BOO!
.sumber
Ya, itu memang solusi mundur yang hampir tidak seperti yang diharapkan seseorang dari bahasa baru yang penuh janji ... tapi karena kekurangan sariawan kita sebenarnya bisa makan burung hitam (senyum).
Tetapi jika Julia belum berencana untuk memperhitungkan sinyal sistem dari dunia Unix / Linux, mungkin dimungkinkan untuk melakukannya dengan menggunakan pustaka C seperti yang diakses oleh signal.h.
Kita harus mendefinisikan fungsi julia melakukan apa yang diharapkan ketika sinyal sistem diterima. Jadikan itu bisa digunakan dalam C sebagai Sig_handler dan panggil dari julia sinyal pernyataan C (SIGWINCH, Sig_handler);
Saya tidak cukup akrab dengan julia untuk menulis kode yang tepat. Tapi ini idenya ...
sumber
ccal
) dan ingin kemudian membuatnya menjadi paket standar Julia, saya dapat membantu mengemasnya.