2015-12-24 2 views
5

से माता-पिता की प्रक्रिया के लिए SIGINT अगर मैं एक लंबे समय से चल systemapt-cache search <some query> की तरह आदेश, वहाँ एक SIGINT इस तरह से ^C के माध्यम से भेजा माता पिता पर्ल की प्रक्रिया के लिए कमांड लाइन पर अग्रेषित करने के लिए एक रास्ता है कि सभी बाल प्रक्रियाओं का उपयोग किया जाता है।पर्ल आगे `system` आदेश

इस उदाहरण में वांछित व्यवहार नहीं है। संकेत बच्चे की प्रक्रिया में भेजा जाता है।

#!/usr/bin/env perl 
use strict; 
use warnings FATAL => 'all'; 
use autodie; 

# long running command on ubuntu, produces a ton of output. 
# replace with your favorite long running command 
system("apt-cache search hi"); 

print("Perl did not catch SIGINT even with autodie\n"); 

मैं बच्चे कि system("apt-cache search hi &") द्वारा बनाई किया जाएगा पीआईडी ​​पर कब्जा करने के तरीके के लिए चारों ओर खोज करने की कोशिश की, लेकिन किसी भी नहीं मिल सका, तो मैं fork आईएनजी और exec प्रक्रिया ing और एक संकेत हैंडलर लेखन की कोशिश की। यह काम नहीं करता है क्योंकि apt-cache ने clone सिस्टम कॉल के माध्यम से कुछ प्रक्रियाएं लॉन्च की हैं। कुछ तर्क हाथ से रोलिंग प्रक्रिया पेड़ का हिस्सा चलना और

#!/usr/bin/env perl 
use strict; 
use warnings FATAL => 'all'; 
use autodie; 

my $cpid; 

$SIG{INT} = sub { 
    kill 'KILL', $cpid; 
    exit; 
}; 

# long running command on ubuntu, produces a ton of output. 
# replace with your favorite long running command 
$cpid = fork; 
if ($cpid == 0) { 
    exec 'apt-cache', 'search', 'hi'; 
} 

print "Perl did not catch SIGINT even with autodie\n"; 

मैं अनिवार्य रूप से लगता है कि मैं क्या चाहते हैं तो SIGINT की तरह एक संकेत की वजह से या तो का निर्धारण करने में एक बच्चे की प्रक्रिया system से बाहर निकल गया द्वारा शुरू की है कि क्या का एक तरीका है साफ करने के लिए मेरे पास पर्ल स्क्रिप्ट स्वयं के बाद साफ हो सकती है या बाल प्रक्रियाओं को चलाने और उन्हें इस तरह से काटने का तरीका है कि प्रक्रिया प्रबंधन के अजीब किनारे के मामलों को साफ और पोर्टेबल तरीके से संभाला जा सकता है।

+0

'आईपीसी :: रन' सिस्टम की बजाय आपको चाहिए। या वैकल्पिक रूप से, बस 'सिग्लोल्ड' को "इग्नोर" पर सेट करें ताकि वे स्वचालित रूप से बाहर निकल जाएंगे। – Sobrique

+0

यह पता लगाने का एक तरीका है कि उपयोगकर्ता द्वारा आदेश छोड़ा गया था: देखें [सिग्नल नंबर 2 का नाम] (http://stackoverflow.com/questions/29862178/name-of-signal-number-2) –

+0

यह भी देखें [अपने प्रक्रिया समूह में प्रक्रिया कैसे शुरू करें?] (Http://stackoverflow.com/questions/5809034/in-linux-how-to-start-a-process-in-its-own-process-group- और अधिक) –

उत्तर

6

बच्चे को एक प्रक्रिया समूह का प्रमुख बनाएं, फिर पूरे प्रक्रिया समूह को सिग्नल भेजें।

#!/usr/bin/perl 

use strict; 
use warnings; 
use autodie; 

use POSIX qw(setpgid); 

my $child_pid; 

$SIG{INT} = sub { 
    kill INT => -$child_pid if $child_pid; 
    exit(0x80 | 2); # 2 = SIGINT 
}; 

my $child_pid = fork(); 
if (!$child_pid) { 
    setpgid($$); 
    exec 'apt-cache', 'search', 'hi'; 
} 

WAIT: { 
    no autodie; 
    waitpid($child_pid, 0); 
    redo WAIT if $? == -1 and $!{EINTR}; 
    die $! if $? == -1; 
} 

exit(($? >> 8) | (0x80 | ($? & 0x7F))); 
+0

'मार INT => - $ child_pid अगर $ baby_pid; 'क्या यह विंडोज-विशिष्ट है? –

+1

नहीं, काफी विपरीत। विंडोज़ में पॉज़िक्स सिग्नल या प्रोसेस ग्रुप नहीं हैं (हालांकि 'हत्या' का इस्तेमाल कंसोल ऐप को भेजने के लिए किया जा सकता है, विंडोज़ के पास बहुत कम संकेतों में से एक है, Ctrl-C और Ctrl-Break)। – ikegami

+0

तो फिर सीपीआईडी ​​को नकारने से क्या होता है? –

संबंधित मुद्दे