2012-03-02 25 views
5

में जाल का उपयोग करके समाप्त पृष्ठभूमि प्रक्रिया को कैप्चर करें। मैं एक बैश स्क्रिप्ट लिख रहा हूं जो कई पृष्ठभूमि प्रक्रियाओं को जन्म देता है। जब भी कोई प्रक्रिया समाप्त हो जाती है तो मैं अधिसूचित होना चाहता हूं; और मैं समाप्त प्रक्रिया के ढक्कन को जानना चाहता हूं।बैश

मैंने wait का उपयोग करने पर ध्यान दिया है, जैसे प्रत्येक स्पॉन्ड प्रक्रिया की पिड्स कैप्चर की जाती हैं और एक सरणी में संग्रहीत होती हैं, और फिर सरणी को फिर से चालू किया जाता है, और प्रत्येक प्रक्रिया पर प्रतीक्षा कहा जाता है। इस तकनीक को यहां विभिन्न तरीकों से वर्णित है:

https://stackoverflow.com/a/356154/366856

इस के साथ समस्या यह

, अगर मैं इसे सही ढंग से समझ, कि यह अपेक्षाकृत अक्षम करता है, तो आप एक व्यक्ति की प्रक्रिया समाप्त होते ही कुछ काम करवाना चाहते हैं हो सकता है । उदाहरण के लिए, यदि आप ए और बी को संसाधित करते हैं, और बी ए से पहले समाप्त होता है, तो निष्पादन को ए और बी दोनों को समाप्त करने की प्रतीक्षा करनी चाहिए। जैसे ही बी खत्म होता है, मुझे एक क्रिया करने की आवश्यकता होती है।

ऐसा लगता है कि trap SIGCHLD एक बच्चा समाप्त होने पर तत्काल कार्रवाई करने का तरीका है, लेकिन समस्या यह है कि मुझे सिगचल सिग्नल के स्रोत के पिड को निर्धारित करने का कोई तरीका नहीं मिल रहा है, जिसे मुझे भी चाहिए। निकटतम बात मैं इस की एक काम उदाहरण के लिए मिल गया है इस पोस्ट में तीसरे कोड उदाहरण है:

http://www.linuxforums.org/forum/programming-scripting/103996-multithreading-bash.html#post510187

मैं इसे यहाँ कॉपी-पेस्ट करने के सुविधा के लिए:

#!/bin/bash 

iNext=0 

function ChildReturned() { 
     wait $1 
     echo "$1 was returned. Its exits status was: $?" 
     iNext=$((iNext+1)) 
     StartChild $iNext 
} 


function StartChild { 
     ./child $1 & 
     pid=$! 
     echo "Started: $1 PID= $pid" 
     trap 'ChildReturned $pid' SIGCHLD 
} 


set -bm 

for ((iNext=0; iNext<=10; iNext++)); 
do 
     StartChild $iNext 
done 

wait 

मैं लगता है कि यह उदाहरण काम नहीं करता है, क्योंकि लेखक trap को कई बार कॉल करने की गलती करता है, प्रत्येक बार trap के तर्क में एक अलग पिड चर को कैप्चर करता है। प्रत्येक बार जाल कहा जाता है, यह पिछले कॉल को ओवरराइट करता है, और इस प्रकार एक मनमाना पिड पकड़ा जाएगा। मैं एक बेहतर तकनीक खोजने में सक्षम नहीं हूं।

क्या बैश में जाल का उपयोग करके एक समाप्त बाल प्रक्रिया के पिड को पाने का कोई तरीका है?

अद्यतन

मैं सिर्फ इस संसाधन है, जो इस समस्या यह है कि मैं अब तक देखा है के समाधान के लिए सबसे अच्छा, सबसे व्यापक सिंहावलोकन शामिल करने के लिए बात करने के लिए चाहता था:

http://mywiki.wooledge.org/ProcessManagement#I_want_to_process_a_bunch_of_files_in_parallel.2C_and_when_one_finishes.2C_I_want_to_start_the_next._And_I_want_to_make_sure_there_are_exactly_5_jobs_running_at_a_time

+2

http://mywiki.wooledge.org/ProcessManagement – jordanm

+0

'kill -0 $ PID': बहुत उपयोगी! धन्यवाद! – jbeard4

+0

इससे भी बेहतर, अनुभाग कहा जाता है * मैं समानांतर में फ़ाइलों का एक गुच्छा संसाधित करना चाहता हूं, और जब कोई समाप्त होता है, तो मैं अगला शुरू करना चाहता हूं। और मैं यह सुनिश्चित करना चाहता हूं कि एक समय में केवल 5 नौकरियां चल रही हों। * सबसे अच्छा जवाब मैंने अब तक पढ़ा है – jbeard4

उत्तर

3

एक बार जाल सेट करें, और जाल में आप jobs -n पर कॉल कर सकते हैं यह देखने के लिए कि आखिरी बार चेक किए जाने के बाद से कौन से बच्चे समाप्त हुए हैं। ध्यान दें कि यह आपको नहीं बताता कि किस बच्चे ने सिग्चाल्ड भेजा है; उस मामले पर विचार करें जहां जाल में प्रवेश करने से पहले दो बच्चे मर जाते हैं। उस स्थिति में, आप केवल एक बार जाल में प्रवेश करेंगे, और यह एक महत्वपूर्ण मुद्दा है जिसमें बच्चे का सिग्नल आप वास्तव में प्रतिक्रिया दे रहे हैं। ध्यान दें कि -n एक बैश एक्सटेंशन है, और आप jobs -l का उपयोग करना पसंद कर सकते हैं।

+0

कूल, मुझे 'jobs -n' के बारे में पता नहीं था।मुझे लगता है कि यह मेरी समस्या को अच्छी तरह से हल करना चाहिए, और इसलिए मैं इस प्रश्न को हल करने के लिए चिह्नित करने जा रहा हूं। – jbeard4