समानांतर खोल छोरों


11

मैं कई फाइलों को प्रोसेस करना चाहता हूं और चूंकि मुझे यहां कोर का एक गुच्छा मिला है, जो मैं इसे समानांतर में करना चाहता हूं:

for i in *.myfiles; do do_something $i `derived_params $i` other_params; done

मैं एक Makefile समाधान के बारे में जानता हूं, लेकिन मेरे आदेशों को शेल ग्लोबिंग सूची से बाहर तर्कों की आवश्यकता है। मैंने जो पाया वह है:

> function pwait() {
>     while [ $(jobs -p | wc -l) -ge $1 ]; do
>         sleep 1
>     done
> }
>

इसका उपयोग करने के लिए, सभी को एक काम करना होगा और जॉब और एक प्वॉइट कॉल के बाद, पैरामीटर समानांतर प्रक्रियाओं की संख्या देता है:

> for i in *; do
>     do_something $i &
>     pwait 10
> done

लेकिन यह बहुत अच्छी तरह से काम नहीं करता है, उदाहरण के लिए, मैंने इसे कई फ़ाइलों को परिवर्तित करने वाले लूप के लिए उदाहरण के साथ आज़माया, लेकिन मुझे त्रुटि दे दी और नौकरी छोड़ दी।

मैं विश्वास नहीं कर सकता कि यह अभी तक नहीं किया गया है क्योंकि zsh मेलिंग सूची पर चर्चा अब तक बहुत पुरानी है। तो क्या आप कोई बेहतर जानते हैं?


इस प्रश्न के समान: superuser.com/questions/153630/… देखें कि क्या यह तकनीक आपके लिए काम करती है।
JRobert

यदि आप त्रुटि संदेश पोस्ट करते हैं तो यह उपयोगी होगा।
अगली सूचना तक रोक दिया गया।

@JRobert हाँ मुझे यह पता था लेकिन यह वास्तव में मदद नहीं करता है क्योंकि मेकफाइल दृष्टिकोण काम नहीं करेगा जैसा मैंने कहा था! @ डेनिस: ठीक है, पहले मैं एक शीर्ष प्रक्रिया चलाने के लिए मुझे निर्दिष्ट प्रक्रियाओं की संख्या से अधिक दिखा रहा हूं। दूसरा यह ठीक से प्रॉम्प्ट पर वापस नहीं आता है। तीसरा कि मैंने कहा कि यह नौकरियों को छोड़ देता है पूर्ववत ठीक नहीं था: मैंने बस एक संकेतक रखा echo "DONE"था लूप के बाद जिसे सक्रिय नौकरियों के समाप्त होने से पहले निष्पादित किया गया था। => यह मुझे लगता है कि नौकरियों के लिए किया गया था।
गणित

जवाबों:


15

एक मेकफाइल आपकी समस्या का एक अच्छा समाधान है। आप इस समांतर निष्पादन को शेल में प्रोग्राम कर सकते हैं, लेकिन यह कठिन है, जैसा आपने देखा है। मेक का एक समानांतर कार्यान्वयन न केवल नौकरी शुरू करने और उनकी समाप्ति का पता लगाने का ध्यान रखेगा, बल्कि लोड संतुलन को भी संभाल सकता है, जो कि मुश्किल है।

ग्लोबिंग की आवश्यकता एक बाधा नहीं है: ऐसे कार्यान्वयन हैं जो इसका समर्थन करते हैं। GNU मेक, जिसमें वाइल्डकार्ड का विस्तार होता है जैसे कि $(wildcard *.c)और शेल एक्सेस जैसे कि $(shell mycommand)(GNU मेक अप फंक्शन अधिक जानकारी के लिए मैनुअल बनाते हैं)। यह makeलिनक्स पर डिफ़ॉल्ट है, और अधिकांश अन्य प्रणालियों पर उपलब्ध है। यहाँ एक मेकफाइल कंकाल है जिसे आप अपनी आवश्यकताओं के अनुसार ढाल सकते हैं:

स्रोत = $ (वाइल्डकार्ड * .src)

सभी: $ (स्रोत: .src = .tgt)

% .tgt: $ .src
    do_something $ <$$ (व्युत्पन्न_ $ $ <)> $ @

make -j4समानांतर में चार नौकरियों को निष्पादित करने या make -j -l33 के आसपास लोड औसत रखने के लिए कुछ चलाएं ।


8

मुझे यकीन नहीं है कि आपके व्युत्पन्न तर्क क्या हैं। लेकिन जीएनयू समानांतर http: // www.gnu.org/software/parallel/ के साथ आप प्रति व्यक्ति एक नौकरी चलाने के लिए ऐसा कर सकते हैं:

find . | parallel -j+0 'a={}; name=${a##*/}; upper=$(echo "$name" | tr "[:lower:]" "[:upper:]");
   echo "$name - $upper"'

यदि आप जो प्राप्त करना चाहते हैं, वह केवल।

parallel -j+0 lame {} -o {.}.mp3 ::: *.wav

जीएनयू के समानांतर वीडियो को http://www.youtube.com/watch?v=OpaiGYxkSuQ पर देखें


7

आपके लिए शेल के waitकमांड काम का उपयोग नहीं करेगा ?

for i in *
do
    do_something $i &
done
wait

आपका लूप किसी काम को अंजाम देता है, फिर उसका इंतजार करता है, फिर अगली नौकरी करता है। यदि ऊपर वाला आपके लिए काम नहीं करता है, तो आप आगे बढ़ने pwaitपर आपका काम बेहतर हो सकता है done


1 मिलियन फ़ाइलों के साथ नहीं, मेरे पास 1 मिलियन प्रक्रियाएं चल रही हैं, या क्या मैं गलत हूं?
गणित

1
@brubelsabs: खैर, यह एक लाख प्रक्रियाएं करने की कोशिश करेगा । आपने अपने प्रश्न में यह नहीं कहा कि आपको कितनी फ़ाइलों को संसाधित करने की आवश्यकता है। मुझे लगता है कि आपको forसीमित करने के लिए नेस्टेड लूप्स का उपयोग करने की आवश्यकता होगी : for file in *; do for i in {1..10}; do do_something "$i" & done; wait; done(अनटाइटेड) जो एक समय में दस करना चाहिए और अगले दस को शुरू करने से पहले प्रत्येक समूह के सभी दस होने तक इंतजार करना चाहिए। आपका लूप एक बार में एक बार &मूट बनाता है । वह प्रश्न देखें जो JRobert अन्य विकल्पों के लिए जुड़ा हुआ है। आपके (और उस एक) के समान अन्य प्रश्नों के लिए स्टैक ओवरफ्लो पर खोजें।
अगली सूचना तक रोक दिया गया।

अगर ओपी एक लाख फाइलों की उम्मीद करता है तो उसे समस्या होगी for i in *। उसे एक पाइप या कुछ और के साथ लूप में तर्क पारित करना होगा। फिर एक आंतरिक लूप के बजाय आप एक वृद्धि काउंटर चला सकते हैं और "micro-"wait"-s"हर "$ ((%% 32))" "-eq '0' को चला सकते हैं

@ डेनिसविलियम्सन: waitएक आंतरिक काउंटर लूप के साथ संयोजन करना मेरे लिए अच्छी तरह से काम किया। धन्यवाद!
जोएल पुरा

3

किसी ने अभी तक xargs का उल्लेख क्यों नहीं किया है?

यह मानते हुए कि आपके पास तीन तर्क हैं,

for i in *.myfiles; do echo -n $i `derived_params $i` other_params; done | xargs -n 3 -P $PROCS do_something

अन्यथा एक सीमांकक का उपयोग करें (नल उस के लिए आसान है):

for i in *.myfiles; do echo -n $i `derived_params $i` other_params; echo -ne "\0"; done | xargs -0 -n 1 -P $PROCS do_something

EDIT: उपरोक्त के लिए, प्रत्येक पैरामीटर को एक अशक्त वर्ण से अलग किया जाना चाहिए, और फिर पैरामीटर की संख्या को xargs -n के साथ निर्दिष्ट किया जाना चाहिए।


हाँ, हमारे प्रोजेक्ट में किसी को एक ही विचार है, और यह एमएसआई के साथ विंडोज के तहत भी बहुत अच्छा काम करता है।
गणित

0

मैंने कुछ उत्तरों की कोशिश की। वे स्क्रिप्ट को जरूरत से ज्यादा जटिल बनाते हैं। आदर्श रूप से उपयोग parallelया xargsबेहतर होगा, लेकिन अगर लूप के लिए संचालन जटिल है, तो समानांतर को आपूर्ति करने के लिए एक बड़ी और लंबी लाइनों की फाइलें बनाने के लिए यह समस्याग्रस्त हो सकता है। इसके बजाय हम स्रोत का उपयोग इस प्रकार कर सकते हैं

# Create a test file 
$ cat test.txt
task_test 1
task_test 2

# Create a shell source file 
$ cat task.sh
task_test()
{
    echo $1
}

# use the source under bash -c 
$ cat test.txt | xargs -n1 -I{} bash -c 'source task.sh; {}'
1
2

इस प्रकार आपकी समस्या का समाधान जैसा दिखेगा

for i in *.myfiles; echo " do_something $i `derived_params $i` other_params
" >> commands.txt ; done

कुछ के रूप में परिभाषित करें do_something.sh

do_something(){
process $1
echo $2 
whatever $3 

}

के साथ निष्पादित xargयाgnu parallel

   cat commands.txt | xargs -n1 -I{} -P8 bash -c 'source do_something.sh; {}'

मुझे लगता है कि इसके लिए पुनरावृत्तियों की कार्यात्मक स्वतंत्रता निहित है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.