जूलिया में सिस्टम सिग्नल इंटरसेप्शन


9

जूलिया प्रोग्राम में जो लिनक्स के तहत चलता है, मुझे कंसोल विंडो के आकार बदलने पर एक समर्पित कार्रवाई शुरू करने की आवश्यकता है। तो कैसे जूलिया में, मैं सिस्टम सिग्नल SIGWINCH (खिड़की का आकार बदलना) को रोक सकता हूं और इसे एक फ़ंक्शन में संलग्न कर सकता हूं जो आवश्यक कार्रवाई करता है?

Ada में इसे घोषित करना सीधा है:

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

स्कीम के विचार पर आधारित तम्बू समाधान: मैं एक सी लाइब्रेरी का उपयोग करने की कोशिश करता हूं जो 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 -sared -fPIC -o myLibrary.so myLibrary.o

जूलिया में कार्यक्रम जो सी-लाइब्रेरी का उपयोग करता है:

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 

जूलिया कार्यक्रम ठीक से चलता है लेकिन जब टर्मिनल विंडो को आकार दिया जाता है तो एक सेगमेंटेशन फॉल्ट (कोर डंप किया गया) जारी किया जाता है और प्रोग्राम को कोड: 139 के साथ बाहर कर दिया जाता है।

तो सवाल यह है कि यह विभाजन दोष कहाँ से आता है? संकलन मॉडल से? जूलिया को मेमोरी के हिस्से में कोड निष्पादन को नियंत्रित करने का अधिकार नहीं है जहां सी सिग्नल मॉनिटरिंग का प्रबंधन करता है?

सिग_हैंडलर में प्रिंटलाइन ऑपरेशन को हटाने से विभाजन दोष को दबा दिया गया:

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 ((: सिग्नल ...) और @cfunction का उपयोग करके एक सिग्नलहैंडलर.ज्ल मॉड्यूल के रूप में इसे वास्तविक रूप से सीधा करने के लिए काफी सरल होना चाहिए, लेकिन AFAIK यह नहीं किया गया है।
बिल

आपका सुझाव अच्छा था। धन्यवाद।
एमिल

जवाबों:


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!


मुझे वर्तमान कंसोल विंडो आकार प्राप्त करने का यह अच्छा तरीका नहीं पता था। प्रदर्शित करता है (stdout) धन्यवाद
एमिल

0

हां, यह वास्तव में एक पतन समाधान है जो शायद ही कोई वादा करता है कि वादों से भरी एक नई भाषा से ... लेकिन थ्रश की कमी के लिए हम वास्तव में ब्लैकबर्ड (मुस्कान) खा सकते हैं।

लेकिन अगर जूलिया ने यूनिक्स / लिनक्स दुनिया के सिस्टम सिग्नल को ध्यान में रखने में सक्षम होने की योजना नहीं बनाई है, तो यह संभव हो सकता है कि वह सी लाइब्रेरी का उपयोग कर सकता है जैसे कि सिग्नल। एच एक्सेस।

 #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;
}

हमें एक जूलिया फ़ंक्शन को परिभाषित करना होगा जो सिस्टम सिग्नल प्राप्त होने पर अपेक्षित है। इसे C में Sig_handler के रूप में प्रयोग करने योग्य बनाएं और जूलिया से C स्टेटमेंट सिग्नल (SIGWINCH, Sig_handler) पर कॉल करें;

मैं जूलिया के साथ सटीक कोड लिखने के लिए पर्याप्त परिचित नहीं हूं। लेकिन यह विचार है ...


आप जो प्रस्ताव देंगे, मैं उसे लागू करने की कोशिश करूंगा।
एमिल

@Emile यदि आप इसे लागू करने का प्रबंधन करते हैं (जूलिया के लेखन सहित ccal) और बाद में इसे एक मानक जूलिया पैकेज में बनाना चाहते हैं तो मैं पैकेजिंग के साथ मदद कर सकता हूं।
प्रेज़ेमीस्लाव सूज़ेल

विधिवत् नोट किया हुआ ! मुझे जूलिया डॉक्यूमेंटेशन में थोड़ा आगे रहना होगा।
एमिल

@Przemyslaw Szufel: ऊपर दिए गए विभाजन दोष का क्या विश्लेषण है, जो मेरे प्रश्न के पूरक के रूप में दिखाया गया है और जब सी फ़ंक्शन रुकावट को पकड़ने के लिए उपयोग किया जाता है?
एमिल

मैं जूलिया-सी एकीकरण कोड नहीं लिख रहा हूं। हालांकि, मुझे पता है कि बहुत लंबे समय तक एक सेगफ़ॉल्ट त्रुटि हुई थी जब भी जूलिया थ्रेड्स में किसी भी सिस्टम IO का उपयोग किया गया था, तो शायद वहाँ कुछ मुद्दे हैं। हो सकता है कि पहले चरण में यह देखने की कोशिश करें कि टर्मिनल साइज पूछे बिना आप क्या खुशी मनाते हैं।
प्रेज़ेमीस्लाव स्ज़ुफ़ेल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.