الحد الأدنى من "قائمة انتظار المهام" مع أدوات Linux المخصصة للاستفادة من وحدة المعالجة المركزية متعددة النواة

StackOverflow https://stackoverflow.com/questions/832253

  •  06-07-2019
  •  | 
  •  

سؤال

ما هي أفضل/أسهل طريقة لإنشاء نظام قائمة انتظار المهام البسيط لنظام التشغيل Linux باستخدام أدوات bash والأدوات الشائعة؟

لدي ملف يحتوي على 9000 سطر، كل سطر به سطر أوامر bash، والأوامر مستقلة تمامًا.

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

يحتوي صندوقي على أكثر من نواة واحدة وأريد تنفيذ مهام X في نفس الوقت.لقد بحثت في الويب عن طريقة جيدة للقيام بذلك.من الواضح أن الكثير من الناس يعانون من هذه المشكلة ولكن لا أحد لديه حل جيد حتى الآن.

سيكون من الرائع أن يكون الحل يحتوي على الميزات التالية:

  • يمكن تفسير أكثر من أمر واحد (على سبيل المثال. command; command)
  • يمكن تفسير عمليات إعادة توجيه الدفق على الخطوط (على سبيل المثال. ls > /tmp/ls.txt)
  • يستخدم فقط أدوات Linux الشائعة

نقاط إضافية إذا كانت تعمل على نسخ يونكس أخرى دون متطلبات غريبة جدًا.

هل كانت مفيدة؟

المحلول

هل يمكنك تحويل قائمة الأوامر الخاصة بك إلى Makefile؟إذا كان الأمر كذلك، يمكنك فقط تشغيل "make -j X".

نصائح أخرى

جنو الموازي http://www.gnu.org/software/parallel/ هي أداة أكثر عمومية للتوازي من PPSS.

إذا كان ملف التشغيل يحتوي على:

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

يمكنك ان تفعل:

cat runfile | parallel -j+0

والتي سيتم تشغيل أمر واحد لكل وحدة المعالجة المركزية الأساسية.

إذا كانت أوامرك بسيطة كما هو مذكور أعلاه، فلن تحتاج حتى إلى ملف تشغيل ولكن يمكنك القيام بما يلي:

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

إذا كان لديك المزيد من أجهزة الكمبيوتر المتاحة للقيام بالمعالجة، فقد ترغب في إلقاء نظرة على خيارات --sshlogin و --trc لـ GNU Parallel.

حسنًا، بعد نشر السؤال هنا، وجدت المشروع التالي الذي يبدو واعدًا: ppss.

يحرر:ليس هذا ما أريده تمامًا، إذ يركز PPSS على معالجة "جميع الملفات الموجودة في الدليل A".

حسنًا، هذا نوع من الأسئلة الممتعة على أية حال.

هذا ما سأفعله، على افتراض باش(1) بالطبع.

  • اكتشف عدد هذه الأوامر التي يمكن تشغيلها بشكل مفيد بشكل متزامن.لن يقتصر الأمر على عدد النوى فقط؛سيتم تعليق الكثير من الأوامر للإدخال/الإخراج وهذا النوع من الأشياء.اتصل بهذا الرقم N. N=15 على سبيل المثال.
  • قم بإعداد معالج إشارة اعتراض لإشارة SIGCHLD، والذي يحدث عند انتهاء عملية فرعية. trap signalHandler SIGCHLD
  • قم بتجميع قائمة الأوامر الخاصة بك في أنبوب
  • اكتب حلقة تقرأ stdin وتنفذ الأوامر واحدًا تلو الآخر، مما يؤدي إلى تقليل العداد.عندما يكون العداد 0، فإنه waitس.
  • معالج الإشارة الخاص بك، والذي يعمل على SIGCHLD، الزيادات هذا العداد.

والآن، يتم تشغيله أولاً N يأمر ثم ينتظرعندما ينتهي الطفل الأول، يعود الانتظار، ويقرأ سطرًا آخر، ويقوم بتشغيل أمر جديد، وينتظر مرة أخرى.

الآن، هذه هي الحالة التي تعتني بالعديد من الوظائف التي تنتهي بالقرب من بعضها البعض.أنا يشتبه يمكنك الابتعاد عن إصدار أبسط:

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

الآن، سيبدأ هذا الأمر تشغيل أول 15 أمرًا، ثم يقوم بتشغيل الباقي واحدًا تلو الآخر مع انتهاء بعض الأوامر.

متعة الحوسبة الموزعة المماثلة هي Mapreduce Bash Script:

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

وشكرا للإشارة إلى ppss!

يمكنك استخدام ال com.xargs الأمر، لها --max-procs يفعل ما تريد.على سبيل المثال يصبح حل تشارلي مارتن مع xargs:

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

تفاصيل:

  • X هو عدد العمليات كحد أقصى.على سبيل المثال:س = 15.--max-procs يقوم بالسحر
  • أول tr موجود هنا لإنهاء الأسطر بالبايتات الخالية لخيار xargs --null بحيث لا يتم توسيع إعادة توجيه علامات الاقتباس وما إلى ذلك بشكل خاطئ
  • يقوم bash -c بتشغيل الأمر

لقد اختبرته باستخدام ملف mycommands.sh هذا على سبيل المثال:

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

هذه حالة محددة، ولكن إذا كنت تحاول معالجة مجموعة من الملفات وإنتاج مجموعة أخرى من ملفات الإخراج، فيمكنك بدء عدد #cores من العمليات، والتحقق من وجود ملف إخراج قبل معالجته.يقوم المثال أدناه بتحويل دليل ملفات .m4b إلى ملفات .mp3:

فقط قم بتشغيل هذا الأمر عدة مرات كما لديك النوى:

ls *m4b|أثناء القراءة f;هل اختبار -f $ {f ٪ m4b} mp3 || mencoder -of rawaudio "$ f" -oac mp3lame -ovc copy -o $ {f ٪ m4b} mp3 ؛منتهي &

يمكنك رؤية قائمة انتظار المهام الخاصة بي مكتوبة على bash: https://github.com/pavelpat/yastq

قائمة انتظار المهام + الإضافة المتوازية + الديناميكية

باستخدام FIFO، يقوم هذا البرنامج النصي بتفرع نفسه لمعالجة قائمة الانتظار.بهذه الطريقة، يمكنك إضافة أوامر إلى قائمة الانتظار بسرعة (عندما تكون قائمة الانتظار قد بدأت بالفعل).

الاستخدام:أمر ./queue [# الأطفال] [اسم قائمة الانتظار]

مثال، مع موضوع واحد:

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

انتاج:

ONE
TWO

مثال، مع 2 موضوع:

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

انتاج:

TWO
ONE

مثال، مع طابورتين:

./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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top