একই সাথে কমান্ডের সংখ্যার সীমাবদ্ধতার সাথে সমান্তরালভাবে কমান্ড পরিচালনা করা


23

অনুক্রমিক: for i in {1..1000}; do do_something $i; done- খুব ধীর

সমান্তরাল: for i in {1..1000}; do do_something $i& done- খুব বেশি বোঝা

সমান্তরালভাবে কমান্ডগুলি কীভাবে চালানো যায়, তবে এর চেয়ে বেশি নয়, উদাহরণস্বরূপ, প্রতি মুহূর্তে 20 টি উদাহরণ?

এখন সাধারণত হ্যাকের মতো ব্যবহার করা for i in {1..1000}; do do_something $i& sleep 5; doneহয় তবে এটি কোনও ভাল সমাধান নয়।

আপডেট 2 : গৃহীত উত্তরগুলিকে একটি স্ক্রিপ্টে রূপান্তরিত: http://vi-server.org/vi/parallel

#!/bin/bash

NUM=$1; shift

if [ -z "$NUM" ]; then
    echo "Usage: parallel <number_of_tasks> command"
    echo "    Sets environment variable i from 1 to number_of_tasks"
    echo "    Defaults to 20 processes at a time, use like \"MAKEOPTS='-j5' parallel ...\" to override."
    echo "Example: parallel 100 'echo \$i; sleep \`echo \$RANDOM/6553 | bc -l\`'"
    exit 1
fi

export CMD="$@";

true ${MAKEOPTS:="-j20"}

cat << EOF | make -f - -s $MAKEOPTS
PHONY=jobs
jobs=\$(shell echo {1..$NUM})

all: \${jobs}

\${jobs}:
        i=\$@ sh -c "\$\$CMD"
EOF

নোট করুন যে এটি কার্যকর করতে আপনাকে "i =" এর আগে 2 টি ট্যাব দিয়ে 8 টি স্পেস প্রতিস্থাপন করতে হবে।

উত্তর:


15

জিএনইউ সমান্তরাল এটি জন্য তৈরি করা হয়।

seq 1 1000 | parallel -j20 do_something

এমনকি এটি দূরবর্তী কম্পিউটারগুলিতে কাজ চালাতে পারে। সার্ভার 2 এবং স্থানীয় কম্পিউটারে সিপিইউ কোরে 1 জন কাজ চালিয়ে ওজিজি তে এমপি 3 পুনরায় এনকোড করার উদাহরণ এখানে রয়েছে:

parallel --trc {.}.ogg -j+0 -S server2,: \
     'mpg321 -w - {} | oggenc -q0 - -o {.}.ogg' ::: *.mp3

জিএনইউ সমান্তরালে একটি ইন্ট্রো ভিডিও এখানে দেখুন:

http://www.youtube.com/watch?v=OpaiGYxkSuQ


"Moreutils" সম্পর্কে জানেন না এবং এটি ইতিমধ্যে কাজের জন্য একটি সরঞ্জাম রয়েছে। দেখছি এবং তুলনা করছি।
vi।

1
parallelMoreutils মধ্যে গনুহ সমান্তরাল নয় এবং বেশ তার বিকল্পগুলিতে সীমাবদ্ধ। উপরের কমান্ডটি মুরতালীর সমান্তরাল দিয়ে চলবে না।
ওলে টেঞ্জ

1
আরও একটি বিকল্প: xargs --max-procs=20
vi।

4

কোনও ব্যাশ সমাধান নয়, তবে আপনার সম্ভবত একটি মেকফিল ব্যবহার করা উচিত, সম্ভবত -lকিছুটা বেশি লোড অতিক্রম না করা।

NJOBS=1000

.PHONY = jobs
jobs = $(shell echo {1..$(NJOBS)})

all: $(jobs)

$(jobs):
    do_something $@

তারপরে একবারে 20 টি কাজ শুরু করুন

$ make -j20

বা 5 এর বেশি লোড ছাড়াই যতটা সম্ভব চাকরি শুরু করা

$ make -j -l5

আপাতত নন-হ্যাকি সমাধানের মতো মনে হচ্ছে।
vi।

2
echo -e 'PHONY=jobs\njobs=$(shell echo {1..100000})\n\nall: ${jobs}\n\n${jobs}:\n\t\techo $@; sleep `echo $$RANDOM/6553 | bc -l`' | make -f - -j20এখন এটি আরও হ্যাকি লাগছে।
vi।

@vi: ওহ আমার ....
বেঞ্জামিন Bannier

আপনার সমাধানটিকে একটি স্ক্রিপ্টে রূপান্তরিত করেছেন। এখন এটি সহজেই ব্যবহার করা যেতে পারে।
vi।

2

বিন্যাস সহ প্রশ্নটিতে স্ক্রিপ্ট পোস্ট করা:

#!/bin/bash

NUM=$1; shift

if [ -z "$NUM" ]; then
    echo "Usage: parallel <number_of_tasks> command"
    echo "    Sets environment variable i from 1 to number_of_tasks"
    echo "    Defaults to 20 processes at a time, use like \"MAKEOPTS='-j5' parallel ...\" to override."
    echo "Example: parallel 100 'echo \$i; sleep \`echo \$RANDOM/6553 | bc -l\`'"
    exit 1
fi

export CMD="$@";

true ${MAKEOPTS:="-j20"}

cat << EOF | make -f - -s $MAKEOPTS
PHONY=jobs
jobs=\$(shell echo {1..$NUM})

all: \${jobs}

\${jobs}:
        i=\$@ sh -c "\$\$CMD"
EOF

মনে রাখবেন যে "i =" এর আগে আপনাকে অবশ্যই 8 টি স্পেস 2 টি ট্যাব দিয়ে প্রতিস্থাপন করতে হবে।


1

একটি সহজ ধারণা:

আমি 20 মডিউল পরীক্ষা করে দেখুন এবং do_soming এর আগে ওয়েল শেল-কমান্ড কার্যকর করুন।


এটি হয় সমস্ত বর্তমান কাজগুলি সমাপ্ত হওয়ার জন্য (কার্য প্লটের সংখ্যায় সাগ তৈরি করা) অপেক্ষা করবে বা একটি নির্দিষ্ট কাজের জন্য অপেক্ষা করবে যা দীর্ঘ সময়ের জন্য স্টল করতে পারে (আবার এই ক্ষেত্রে sags তৈরি করতে পারে)
vi।

@ ভিআই: শেল ওয়েট এই শেলটির সাথে সম্পর্কিত সমস্ত পটভূমির কাজগুলির জন্য।
harrymc

1

আপনি psকতগুলি প্রক্রিয়া চালাচ্ছেন তা গণনা করতে আপনি ব্যবহার করতে পারেন এবং যখনই এটি একটি নির্দিষ্ট প্রান্তিকের নীচে নেমে আসে আপনি অন্য প্রক্রিয়া শুরু করেন।

সুডোকোড:

i = 1
MAX_PROCESSES=20
NUM_TASKS=1000
do
  get num_processes using ps
  if num_processes < MAX_PROCESSES
    start process $i
    $i = $i + 1
  endif
  sleep 1 # add this to prevent thrashing with ps
until $i > NUM_TASKS

1
for i in {1..1000}; do 
     (echo $i ; sleep `expr $RANDOM % 5` ) &
     while [ `jobs | wc -l` -ge 20 ] ; do 
         sleep 1 
     done
done

হতে পারে while [ `jobs | wc -l` -ge 20]; do?
vi।

অবশ্যই, তবে আমার নমুনায়, আমাকে তখন njobsদু'বার গণনা করতে হবে , এবং ঘুমের কাজগুলি চালানো শেল স্ক্রিপ্টগুলিতে পারফরম্যান্স বেশ গুরুত্বপূর্ণ;)
এমএসডাব্লু

মানে আপনার সংস্করণটি প্রত্যাশার মতো কাজ করে না। আমি পরিবর্তন sleep 1করতে sleep 0.1এবং এটি 40-50 পরিবর্তে 20 গড় njobs শুরু তুলনায় আরো 20 কাজ আমরা জন্য কোনো কাজের সমাপ্ত পরার, শুধু 1 সেকেন্ডের অপেক্ষা করবেন অপেক্ষা করতে হবে থাকে তাহলে।
vi।

0

আপনি এটি এইভাবে করতে পারেন।

threads=20
tempfifo=$PMS_HOME/$$.fifo

trap "exec 1000>&-;exec 1000<&-;exit 0" 2
mkfifo $tempfifo
exec 1000<>$tempfifo
rm -rf $tempfifo

for ((i=1; i<=$threads; i++))
do
    echo >&1000
done

for ((j=1; j<=1000; j++))
do
    read -u1000
    {
        echo $j
        echo >&1000
    } &
done

wait
echo "done!!!!!!!!!!"

নামের পাইপগুলি ব্যবহার করে প্রতিবার এটি সমান্তরালে 20 টি শেল চালায়।

আশা করি এটি সাহায্য করবে :)

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.