موازی بیچاره در بش

پست اصلی در وبلاگ من، خوشحالم که بازخورد را درج می کنم!
جلد: کتابهای پاریس، از طریق کلاومارکس
موضوعات:
- اجرای اسکریپت ها به صورت موازی
- ابزارهایی برای محدود کردن مشاغل همزمان
- شیت پردازش پوسته
- مشاغل همزمان با Bash را محدود کنید
- امتیاز: تک لاینر
1) اجرای اسکریپت ها به صورت موازی
تلاش زیادی نمی کند: من با اجرای همزمان دستورات و دستورات اضافه شده، سرعت ساخت را افزایش داده ام. &
علامت علامت:
# stuff can happen concurrently
# use `&` to run in a sub-shell
cmd1 &
cmd2 &
cmd3 &
# wait on sub-processes
wait
# these need to happen sequentially
cmd3
cmd4
echo Done!
کنترل کار یک ویژگی پوسته است: دستورات در یک فرآیند پس زمینه قرار می گیرند و همزمان اجرا می شوند.
حال با فرض اینکه می خواهید بیش از چند دستور را حلقه کنید، به عنوان مثال تبدیل فایل ها:
for file in *.jpg; do
# start optimizing every file at once
jpegoptim -m 45 "${file}" &
done
# finish queue
wait
اجرای بسیاری از فرآیندها به این روش هنوز سریعتر از یک حلقه معمولی است. اما در مقایسه با چند شغل همزمان، هیچ افزایش سرعتی وجود ندارد – حتی کندی های احتمالی در ورودی/خروجی دیسک ناهمگام [Quotation needed].
بنابراین شما می خواهید استفاده کنید
2) ابزارهایی برای محدود کردن مشاغل همزمان
با 1) نصب ابزارهای سفارشی مانند موازی یا xjobs یا 2) تکیه بر xargs، که یک ابزار غنی از ویژگی است اما پیچیده تر است.
در حال تبدیل شدن wait
به xargs
کد در اینجا توضیح داده شده است: یک مثال برای کارهای دسته ای موازی. این مقاله به تفاوتهای کوچکی بین طعمهای POSIX اشاره میکند – به عنوان مثال، کارکرد متفاوت جداکنندهها در BSD/MacOS.
ما گزینه 3) را انتخاب می کنیم – به بررسی ویژگی های آن می پردازیم wait
و jobs
به مدیریت فرآیندها.
با نقل قول از این خلاصه عالی، در اینجا چند دستور مثال برای آنها آورده شده است
3) مدیریت فرآیند پوسته
# run child process, save process id via `$!`
cmd3 & pid=$!
# get job list
jobs
# get job ids only
# note: not available on zsh
jobs -p
# only wait on job at position `n`
# note: slots may turn up empty while
# newer jobs rest in the queue's tail
wait %n
# wait on last job in list
wait %%
# wait on next finishing process
# note: needs Bash 4.3
wait -n
با مثالی از قبل، مطمئن می شویم
4) کارهای همزمان با Bash را محدود کنید
هر بار که یک فرآیند با استفاده به پایان می رسد wait -n
:
for file in *.jpg; do
jpegoptim -m 45 "${file}" &
# still < 3 max job -l ines? continue loop
if [[ $(jobs|wc -l) -lt 3 ]]; then continue; fi
# with 3 jobs, wait for -n ext, then loop
wait -n
done
# finish queue
wait
متاسفانه، این در MacOS کار نخواهد کرد، زیرا محیط های Bash در نسخه های قدیمی ثابت هستند. را جایگزین می کنیم wait -n
فرمان با wait %%
حلقه زدن بر روی سومین/آخرین کار در صف – یک سازش خوب برای گروه های کوچک (1/3 شانس سریع ترین/کندترین/متوسط کار):
for file in *.jpg; do
jpegoptim -m 45 "${file}" &
# still < 3 max job -l ines? continue loop
if [[ $(jobs|wc -l) -lt 3 ]]; then continue; fi
# with 3 jobs, wait for last in line, then loop
wait %%
done
# finish queue
wait
برای توسعه بیشتر کد، میتوان نسخه Bash یا پوستههای جایگزین (zsh در MacOS) را بررسی کرد تا بسته به زمینه، کد را تغییر دهد. من به استفاده از اینها ادامه می دهم:
5) پاداش: تک لاینر
# sequential, slow
time ( for file in *.jpg; do jpegoptim -m 45 "${file}" ; done )
# concurrent, messy
time ( for file in *.jpg; do jpegoptim -m 45 "${file}" & done; wait )
# concurrent, fast/compatible
time ( for file in *.jpg; do jpegoptim -m 45 "${file}" & if [[ $(jobs|wc -l) -lt 3 ]]; then continue; fi; wait %%; done; wait )
# concurrent, fastest
time ( for file in *.jpg; do jpegoptim -m 45 "${file}" & if [[ $(jobs|wc -l) -lt 3 ]]; then continue; fi; wait -n; done; wait )
واقعیت سرگرم کننده
به عنوان پست تولد 20 سالگی توسط parallel
نویسنده Ole Tange توضیح می دهد، نسخه اصلی اهرمی بود make
زیرا امکان فرآیندهای ناهمزمان را نیز فراهم می کند.