2009-05-06 12 views
5

बैश और सामान्य उपकरण का उपयोग करके लिनक्स के लिए न्यूनतम कार्य कतार प्रणाली बनाने का सबसे अच्छा/आसान तरीका क्या है?स्टॉक लिनक्स टूल्स के साथ न्यूनतम "टास्क कतार" मल्टीकोर सीपीयू

मेरे पास 9'000 लाइनों वाली एक फ़ाइल है, प्रत्येक पंक्ति में एक बैश कमांड लाइन है, आदेश पूरी तरह से स्वतंत्र हैं।

command 1 > Logs/1.log 
command 2 > Logs/2.log 
command 3 > Logs/3.log 
... 

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

यह अच्छा होगा अगर समाधान निम्नलिखित विशेषताएं था:

  • एक से अधिक आदेश की व्याख्या कर सकते हैं (जैसे command; command)
  • धारा की व्याख्या कर सकते तर्ज पर पुनर्निर्देश (जैसे ls > /tmp/ls.txt)
  • केवल सामान्य लिनक्स उपकरण

बोनस अंक यदि यह अन्य यूनिक्स-क्लोन पर बहुत ही विदेशी आवश्यकताओं के बिना काम करता है।

उत्तर

13

क्या आप अपनी कमांड सूची को मेकफ़ाइल में बदल सकते हैं? यदि ऐसा है, तो आप बस "मेक-जे एक्स" चला सकते हैं।

+0

बिल्कुल सही, यह एक आकर्षण की तरह काम करता था! – Manuel

0

ठीक है, यहां प्रश्न पोस्ट करने के बाद, मुझे निम्नलिखित प्रोजेक्ट मिला जो आशाजनक लग रहा है: ppss

संपादित करें: मुझे जो कुछ भी चाहिए, वह नहीं है, पीपीएसएस "निर्देशिका ए में सभी फाइलों" को संसाधित करने पर केंद्रित है।

0

ठीक है, यह वैसे भी एक मजेदार सवाल है।

यहां मैं क्या करूँगा, बैश (1) बेशक।

  • पता लगाएं कि इनमें से कितने कमांड उपयोगी रूप से चल सकते हैं। यह सिर्फ कोर की संख्या नहीं होने वाला है; I/O और उस तरह की चीज़ के लिए बहुत से आदेश निलंबित किए जाएंगे। उदाहरण के लिए उस संख्या को एन N=15 पर कॉल करें।
  • SIGCHLD सिग्नल के लिए एक ट्रैप सिग्नल हैंडलर सेट अप करें, जो तब होता है जब कोई बच्चा प्रक्रिया समाप्त हो जाती है। trap signalHandler SIGCHLD
  • बिल्ली एक पाइप
  • में आदेशों की अपनी सूची एक पाश कि stdin पढ़ता है और एक-एक करके आदेशों को निष्पादित करता है, एक काउंटर decrementing लिखें। जब काउंटर 0 है, तो यह wait एस है।
  • आपका सिग्नल हैंडलर, जो सिगचल पर चलता है, वृद्धि काउंटर।

तो अब यह पहला N आदेश चलाता है, फिर प्रतीक्षा करता है। जब पहला बच्चा समाप्त हो जाता है, प्रतीक्षा प्रतीक्षा करता है, यह एक और पंक्ति पढ़ता है, एक नया आदेश चलाता है, और फिर इंतजार करता है।

अब, यह एक ऐसा मामला है जो कई नौकरियों को एक साथ समाप्त करने का ख्याल रखता है।मुझे लगता है आप दूर एक सरल संस्करण के साथ प्राप्त कर सकते हैं:

N=15 
COUNT=N 
cat mycommands.sh | 
while read cmd 
do 
    eval $cmd & 
    if $((count-- == 0)) 
    then 
     wait 
    fi 
od 

अब, यह एक पहले 15 आदेशों से प्रारंभ हो जाएगा, और फिर कुछ आदेश समाप्त के रूप में एक समय में आराम से एक चलाते हैं।

0

इसी प्रकार वितरित-कंप्यूटिंग मजेदार है MapReduce बैश स्क्रिप्ट:

http://blog.last.fm/2009/04/06/mapreduce-bash-script

और PPSS ओर इशारा करते हुए के लिए धन्यवाद!

0

आप xargs आदेश अपने --max-procs आप क्या चाहते हैं करता है उपयोग कर सकते हैं। मिसाल के तौर पर चार्ली मार्टिन समाधान xargs साथ हो जाता है:

tr '\012' '\000' <mycommands.sh |xargs --null --max-procs=$X bash -c 

विवरण:

  • एक्स प्रक्रियाओं अधिकतम की संख्या है। उदा।: एक्स = 15। --max-procs जादू
  • पहले टीआर कर रही है xargs --null विकल्प के लिए अशक्त बाइट्स से लाइनों को समाप्त करने के लिए इतना है कि पुनर्निर्देशन उद्धरण यहाँ है आदि को गलत तरीके से expansed नहीं कर रहे हैं
  • बैश -c आदेश चलाता

मैं उदाहरण के लिए इस mycommands.sh फ़ाइल के साथ यह परीक्षण किया:

date 
date "+%Y-%m-%d" >"The Date".txt 
wc -c <'The Date'.txt >'The Count'.txt 
0

यह एक विशिष्ट मामला है, लेकिन आप फ़ाइलों का एक सेट की प्रक्रिया और उत्पादन फ़ाइलों का एक और सेट का उत्पादन करने की कोशिश कर रहे हैं, तो आप शुरू कर सकते हैं #cores प्रक्रियाओं की संख्या, और प्रो से पहले आउटपुट फ़ाइल मौजूद है या नहीं इसका अनुमान लगाया

बस इस आदेश के रूप में कई बार के रूप में चलाने के आप कोर है: नीचे दिए गए उदाहरण .m4b फ़ाइलों की एक निर्देशिका फ़ाइलें .mp3 में धर्मान्तरित

ls * M4B | जबकि च पढ़ा; test -f $ {f% m4b} एमपी 3 || करें मेनकोडर -of रावाडियो "$ एफ" -ओएसी एमपी 3lame -ovc कॉपी -o $ {f% m4b} एमपी 3; किया &

9

जीएनयू समांतर http://www.gnu.org/software/parallel/ पीपीएसएस की तुलना में समानांतर के लिए एक और सामान्य उपकरण है।

runfile शामिल हैं:

command 1 > Logs/1.log 
command 2 > Logs/2.log 
command 3 > Logs/3.log 

आप कर सकते हैं:

cat runfile | parallel -j+0 

जो सीपीयू कोर प्रति एक आदेश चलेंगे।

अपने आदेश ऊपर के रूप में आप भी runfile की जरूरत नहीं है, लेकिन क्या कर सकते हैं के रूप में सरल कर रहे हैं:

seq 1 3 | parallel -j+0 'command {} > Logs/{}.log' 

आप अधिक कंप्यूटर प्रसंस्करण करने के लिए उपलब्ध है, तो आप --sshlogin को देखने के लिए चाहते हो सकता है और जीएनयू समांतर के लिए - टीआरसी विकल्प।

0

टास्क कतार + parallelized + डायनामिक अलावा

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

उपयोग: ./queue कमान [बच्चों की #] [कतार नाम]

उदाहरण के लिए, 1 धागे से:

 
./queue "sleep 5; echo ONE" 
./queue "echo TWO" 

आउटपुट:

 
ONE 
TWO 

उदाहरण के लिए, के साथ 2 धागा :

 
./queue "sleep 5; echo ONE" 2 
./queue "echo TWO" 

हे utput:

 
TWO 
ONE 

उदाहरण के लिए, 2 कतारों के साथ:

 
./queue "sleep 5; echo ONE queue1" 1 queue1 
./queue "sleep 3; echo ONE queue2" 1 queue2 

आउटपुट:

 
ONE queue2 
ONE queue1 

स्क्रिप्ट ("कतार" और chmod + x कतार के रूप में सहेज):

 

    #!/bin/bash 

    #Print usage 
    [[ $# -eq 0 ]] && echo Usage: $0 Command [# of children] [Queue name] && exit 

    #Param 1 - Command to execute 
    COMMAND="$1" 

    #Param 2 - Number of childs in parallel 
    MAXCHILD=1 
    [[ $# -gt 1 ]] && MAXCHILD="$2" 

    #Param 3 - File to be used as FIFO 
    FIFO="/tmp/defaultqueue" 
    [[ $# -gt 2 ]] && FIFO="$3" 

    #Number of seconds to keep the runner active when unused 
    TIMEOUT=5 

    runner(){ 
     #Associate file descriptor 3 to the FIFO 
     exec 3"$FIFO" 

     while read -u 3 -t $TIMEOUT line; do 
     #max child check 
     while [ `jobs | grep Running | wc -l` -ge "$MAXCHILD" ]; do 
      sleep 1 
     done 

     #exec in backgroud 
     (eval "$line")& 
     done 
     rm $FIFO 
    } 

    writer(){ 
     #fork if the runner is not running 
     lsof $FIFO >/dev/null || ($0 "QueueRunner" "$MAXCHILD" "$FIFO" &) 

     #send the command to the runner 
     echo "$COMMAND" > $FIFO 
    } 

    #Create the FIFO file 
    [[ -e "$FIFO" ]] || mkfifo "$FIFO" 

    #Start the runner if in the runner fork, else put the command in the queue 
    [[ "$COMMAND" == "QueueRunner" ]] && runner || writer 

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