2016-11-10 3 views
2

Ich weiß, wie man ein SIGINT fängt, aber ich weiß nur, wie man den Block irgendwo zufällig in meinen Code steckt. Ich muss in der Lage sein, SIGINT abzufangen, denn wenn eine Datei geschrieben wird (meine Datenbank schreibt häufig in eine Datei), verdirbt sie die Datei. Was ist der ideale Weg, damit umzugehen?Ruby - catch SIGINT, um die Fertigstellung der Datei zu ermöglichen

bearbeiten

In einem Fall behandelt ich diese Funktion durch die Ausführung meines Schreibens, wenn ich ein SIGINT erkennen, aber ich dies zu realisieren wird nicht helfen, wenn ich buchstäblich in der Mitte bin zu schreiben eine Datei mit Marshal.

Gibt es in Ruby keine Möglichkeit, ein SIGINT abzufangen und ihm zu sagen, es zu ignorieren, bis es zum Beispiel fertig ist zu schreiben?

bearbeiten 2

Nevermind, heraus nur eine mögliche Antwort ... siehe unten.

+0

Haben Sie es mit [ 'Signal'] versucht zu kontrollieren (https://ruby-doc.org/core-2.3.1/Signal.html)? Verwenden Sie das, um ein Abschaltflag auszulösen. – tadman

+0

Ich habe 'Falle' in der Vergangenheit benutzt ... aber ich lese nur ein bisschen - sprichst du über die Rettung der Unterbrechung? Wenn ich das machen würde, würde ich einfach die Rescue-Anweisung um den Dateischreibteil legen? – Max

+0

Sie müssen das Signal abfangen, bevor es eine Ausnahme generiert. – tadman

Antwort

0

Ich endete mit einem Rettungsblock, der Interrupt rettet. Im Block wende ich einen booleschen Wert auf wahr. Der boolesche Wert wird zu Beginn jeder meiner Thread-Pool-Aufgaben überprüft, und wenn er wahr ist, wird die gesamte Funktion übersprungen.

bearbeiten

In Bezug auf meine bearbeiten in meinem ursprünglichen Beitrag: Wäre der beste Weg, Interrupts in Datei schreiben zu handhaben sein, wieder einen boolean zu benutzen? Zum Beispiel, erstellen Sie einen Boolean namens interrupt und am Ende des Schreibens in die Datei, überprüfen Sie, ob Boolean ist wahr, und wenn ja, das Programm abbrechen? Ich konnte keine Rettung gebrauchen, um den Interrupt dann zu fangen, aber ich könnte eine Falle benutzen, nein?

0

Das ist, was ich tun würde:

Signal.trap("INT"){ 
    if $lock 
    puts "Not yet done. Please don't interrupt" 
    else 
    puts "Goodbye!" 
    exit 
    end 
} 

def something_long_that_shouldnt_be_interrupted 
    $lock = true 
    10.times do |i| 
    puts "Writing #{i+1}/10. Don't interrupt" 
    sleep 1 
    end 
    $lock = false 
end 

def some_other_process_that_can_be_interrupted 
    10.times do |i| 
    puts "Unimportant stuff #{i+1}/10." 
    sleep 1 
    end 
end 

something_long_that_shouldnt_be_interrupted 
some_other_process_that_can_be_interrupted 


# Writing 1/10. Don't interrupt 
# Writing 2/10. Don't interrupt 
# ^CNot yet done. Please don't interrupt 
# Writing 3/10. Don't interrupt 
# Writing 4/10. Don't interrupt 
# ^CNot yet done. Please don't interrupt 
# Writing 5/10. Don't interrupt 
# ^CNot yet done. Please don't interrupt 
# ^CNot yet done. Please don't interrupt 
# Writing 6/10. Don't interrupt 
# ^CNot yet done. Please don't interrupt 
# Writing 7/10. Don't interrupt 
# Writing 8/10. Don't interrupt 
# ^CNot yet done. Please don't interrupt 
# Writing 9/10. Don't interrupt 
# Writing 10/10. Don't interrupt 
# Unimportant stuff 1/10. 
# Unimportant stuff 2/10. 
# Unimportant stuff 3/10. 
# Unimportant stuff 4/10. 
# ^CGoodbye! 

Wenn Sie es mehr als einmal verwenden zu können, definieren könnte:

def do_not_disturb(&block) 
    $lock = true 
    block.yield 
    $lock = false 
end 

do_not_disturb do 
    # code that shouldn't be interrupted 
end 
Verwandte Themen