সমান্তরালভাবে উত্পাদিত আরও তিনটি স্ট্রিমের মধ্যে একটি একক আউটপুট স্ট্রিম তৈরি করা


10

আমার কাছে তিন ধরণের ডেটা রয়েছে যা বিভিন্ন ফর্ম্যাটে রয়েছে; প্রতিটি ডেটা টাইপের জন্য একটি পাইথন স্ক্রিপ্ট রয়েছে যা এটিকে একক ইউনিফাইড বিন্যাসে রূপান্তর করে।

এই পাইথন স্ক্রিপ্টটি ধীর এবং সিপিইউ-আবদ্ধ (একাধিক-কোর মেশিনে একক কোর), সুতরাং আমি এটির তিনটি দৃষ্টান্ত চালাতে চাই - প্রতিটি তথ্য টাইপের জন্য একটি - এবং তাদের আউটপুটটি এতে প্রবেশের জন্য একত্রিত করতে চাই sort। মূলত: এর সমতুল্য:

{ ./handle_1.py; ./handle_2.py; ./handle_3.py } | sort -n

তবে তিনটি স্ক্রিপ্ট সমান্তরালে চলছে।

আমি এই প্রশ্নটি পেয়েছি যেখানে জিএনইউ splitস্ট্রিমটি পরিচালনা করে এমন কোনও স্ক্রিপ্টের এন দৃষ্টান্তের মধ্যে কিছু স্টডআউট স্ট্রিমকে রাউন্ড-রবিন করার জন্য ব্যবহার করা হচ্ছে।

বিভক্ত মানুষ পৃষ্ঠা থেকে:

-n, --number=CHUNKS
          generate CHUNKS output files.  See below
CHUNKS  may be:
 N       split into N files based on size of input
 K/N     output Kth of N to stdout
 l/N     split into N files without splitting lines
 l/K/N   output Kth of N to stdout without splitting lines
 r/N     like 'l'  but  use  round  robin  distributio

সুতরাং r/Nকমান্ডটি " বিভক্ত রেখা ছাড়াই " বোঝায় ।

এর উপর ভিত্তি করে, এটি মনে হচ্ছে যে নিম্নলিখিত সমাধানগুলি ব্যবহারযোগ্য হওয়া উচিত:

split -n r/3 -u --filter="./choose_script" << EOF
> 1
> 2
> 3
> EOF

এটি কোথায় choose_script:

#!/bin/bash
{ read x; ./handle_$x.py; }

দুর্ভাগ্যক্রমে, আমি কিছু লাইনগুলিতে অন্তর্নির্মিত দেখতে পাচ্ছি - এবং প্রচুর নতুন লাইনের উপস্থিতি নেই।

উদাহরণস্বরূপ, যদি আমি আমার পাইথন স্ক্রিপ্টগুলি কিছু সাধারণ বাশ স্ক্রিপ্টগুলির সাথে প্রতিস্থাপন করি যা এটি করে:

#!/bin/bash
# ./handle_1.sh
while true; echo "1-$RANDOM"; done;

#!/bin/bash
# ./handle_2.sh
while true; echo "2-$RANDOM"; done;

#!/bin/bash
# ./handle_3.sh
while true; echo "3-$RANDOM"; done;

আমি এই আউটপুটটি দেখতে পাচ্ছি:

1-8394

2-11238
2-22757
1-723
2-6669
3-3690
2-892
2-312511-24152
2-9317
3-5981

এটি বিরক্তিকর - আমি উপরে পেস্ট করা ম্যান পেজ এক্সট্রাক্টের ভিত্তিতে এটি লাইন অখণ্ডতা বজায় রাখা উচিত।

স্পষ্টতই এটি কাজ করে যদি আমি -uযুক্তিটি সরিয়ে ফেলি তবে তবে এটি বাফার হয়ে গেছে এবং আমি স্মৃতি থেকে বেরিয়ে যাব কারণ এটি স্ক্রিপ্টগুলির মধ্যে একটি ব্যতীত সকলের আউটপুটকে বাফার করে।

এখানে কারও কিছু অন্তর্দৃষ্টি থাকলে এটি প্রশংসিত হবে। আমি এখানে আমার গভীরতার বাইরে।


ফ্রেইনোডে # ব্যাশের কিছু লোক পরামর্শ দিয়েছিলেন যে আমি তিনটি প্রক্রিয়া নিয়ে সেগুলি ব্যাকগ্রাউন্ড করে কাস্টম এফডিগুলিতে লিখেছি, তারপরে সেই এফডিগুলি লুপ করব এবং তাদের জন্য লাইন পড়ি, তবে কীভাবে কীভাবে এটি কার্যকর করা যায় তা আমি খুঁজে পাইনি। আমাকে coprocবিল্ট ইন ব্যাশের দিকে নজর দিতেও বলা হয়েছিল , যদিও আমি সত্যিই এটি কীভাবে প্রযোজ্য তা দেখতে পাই না।
Cera

1
আপনি কি মধ্যবর্তী ফাইলগুলি ছাড়া এটি করতে হবে? তুমি কি করতে পার না job1.py > file1 & job2.py > file 2 & job3.py > file3 ; wait ; sort -n file1 file2 file3?
অ্যাঙ্গাস

উত্তর:


2

GNU সমান্তরাল -u বিকল্পটি ব্যবহার করে দেখুন।

echo "1\n2\n3" | parallel -u -IX ./handle_X.sh

এটি কোনও প্রক্রিয়া সম্পূর্ণরূপে বাফার না করে এগুলিকে সমান্তরালে চালায়।


আমি একটু বিভ্রান্ত নই - হয় Xমধ্যে IXকহন -Iযে এক্স প্রতিস্থাপন জন্য তা পতাকাঙ্কিত হতে হবে, অথবা এটি আবেদন করা হয় -Xপতাকা, যা আপাতদৃষ্টিতে একটি প্রাসঙ্গিক অর্থ আছে?
Cera

Hmph। আমি এটি করছি: parallel -u -X ./handle_{}.sh ::: "1" "2" "3"এবং দুর্ভাগ্যক্রমে আমি এখনও কিছু আউটপুট ম্যাংলিং দেখছি।
Cera

প্রাক্তন: আপনি এটি ব্যবহার করতে পারেন parallel -u ./handle_{}.shতবে আমি এটি পরিবর্তন করতে পছন্দ করি, কারণ ধনুর্বন্ধকের সাথে কমান্ড একসাথে যোগদান করার অর্থও রয়েছে (আপনার প্রশ্নের মতো)।
ফ্লোব্লোক

আমার জন্য কাজ করার মতো মনে হচ্ছে, আমার গ্রেপ কোনও ম্যাংলিং বাছাই করে না: pastie.org/5113187 (আপনি কি পরীক্ষার ব্যাশ স্ক্রিপ্টগুলি ব্যবহার করছেন, বা আপনার আসল পাইথন স্ক্রিপ্টগুলি ব্যবহার করছেন?)
ফ্লোব্লোক

সমস্যাটি হ'ল এটি আসলে সমান্তরালে কিছু করছে না। আমি ব্যাশ স্ক্রিপ্টগুলি ব্যবহার করছি - pastie.org/5113225
Cera

2

চেষ্টা করুন:

parallel ::: ./handle_1.py ./handle_2.py ./handle_3.py

যদি handle_1.pyকোনও ফাইলের নাম নেয়:

parallel ::: ./handle_1.py ./handle_2.py ./handle_3.py ::: files*

আপনি আউটপুট মিশ্রিত করতে চান না, সুতরাং -u ব্যবহার করবেন না।

আপনি যদি অর্ডারটি রাখতে চান (সুতরাং সমস্ত হ্যান্ডেল_1 আউটপুট হ্যান্ডেল 3 এর আগে এবং সুতরাং আপনি বাছাই এড়াতে সক্ষম হতে পারেন):

parallel -k  ::: ./handle_1.py ./handle_2.py ./handle_3.py ::: files*

আপনি যদি এখনও এটি বাছাই করতে চান তবে আপনি সাজানোর সমান্তরাল করে ব্যবহার করতে পারেন sort -m:

parallel --files "./handle_{1}.py {2} | sort -n"  ::: 1 2 3 ::: files* | parallel -j1 -X sort -m

আউটপুট ধরে রাখার জন্য যথেষ্ট বড় এমন একটি ডিয়ারকে $ TMPDIR সেট করুন।


1
আমি আউটপুটটি 'মিশ্রিত' চাই - আমি কেবলমাত্র নিশ্চিত করতে চাই যে চূড়ান্ত আউটপুটে প্রতিটি লাইন একটি উপ-প্রক্রিয়া থেকে একক লাইন is আমি যদি এটি মিশ্রণ না করি তবে স্ট্যান্ডআউট স্ট্রিমগুলি এখনও মুদ্রিত হচ্ছে না এমন সিস্টেমের মেমরি শেষ হবে।
Cera

জিএনইউ সমান্তরাল দিয়ে আপনি মেমরিটি শেষ করবেন না: এটি মেমরিতে বাফার করে না। কেন আপনি মনে করেন এটি স্মরণে বাফার করে?
ওলে টেঞ্জ

2

হয়তো আমি কিছু মিস করছি, তবে আপনি কেবল এটি করতে পারবেন না:

(./handle_1.py & ./handle_2.py & ./handle_3.py) | sort -n

যদি আপনি প্রতিটি প্রক্রিয়া থেকে লাইনগুলি আন্তঃবিবাহিত না হওয়ার জন্য চান তবে সম্ভবত এটি নিশ্চিত করা সহজ যে প্রক্রিয়াটি তাদের সম্পূর্ণরূপে লিখবে এবং সম্ভবত writeকোনও পাইপের কাছে এস আউটপুট বাফারিং অক্ষম করা হবে যতক্ষণ না তারা তার চেয়ে বড় না হয় ততক্ষণ পরমাণু হওয়ার গ্যারান্টিযুক্ত রয়েছে are PIPE_BUF। উদাহরণস্বরূপ, আপনি নিশ্চিত করুন যে এটি বানাতে পারে না a la ব্যবহার আউটপুট বাফার উপলব্ধ stdioএবং কল fflushবা যাই হোক না কেন সমতুল্য হয় pythonএকের পর এক বা কয়েক লাইন লিখিত হয়েছে।

আপনি অজগর স্ক্রিপ্টগুলি সংশোধন করতে না পারলে আপনি এটি করতে পারেন:

lb() { grep --line-buffered '^'; }

(জিএনইউ গ্রেপ সহ) বা:

lb() while IFS= read -r l; do printf '%s\n' "$l"; done

(কমান্ড আউটপুটটি কী টেক্সট নয় তা নীচের মন্তব্যে নোটগুলি দেখুন)

এবং কর:

(./handle_1.py | lb & ./handle_2.py | lb & ./handle_3.py | lb) | sort -n

এই 3 টি lbপ্রক্রিয়াটি এড়ানোর জন্য অন্য বিকল্পটি হ'ল একটি কমান্ডে তিনটি পাইপ রয়েছে যা ব্যবহার করে select/ pollদেখতে আসে যে কোনও আউটপুট কোথা থেকে আসছে এবং sortলাইন ভিত্তিক এটিকে খাওয়ান , তবে এটি প্রোগ্রামিং কিছুটা সময় নেয়।


আপনার waitমনে হয় সেখানে প্রবেশ করা উচিত ।
ডারোবার্ট

1
না যদি না কিছু প্রোগ্রাম প্রস্থানের আগে তাদের স্টাডআউট বন্ধ করে দেয়, কারণ পাইপটি এতে থাকে এবং sort -nযতক্ষণ না এটিতে একটি এফডি খোলা থাকে সমস্ত প্রোগ্রাম বের না হওয়া অবধি থাকে remain
স্টাফেন চেজেলাস

সত্যিই, আমি পরীক্ষা করেছি, আপনি সঠিক।
ডার্বোবার্ট

না, আমি এখনও ম্যাংলেড আউটপুট পাই। লাইনগুলি একত্রে মিশে যায় এবং আন্তঃবাহিত হয়।
Cera

1
ঠিক আছে @ সেরালেস, আমার আপডেট হওয়া উত্তরটি দেখুন
স্টাফেন চ্যাজেলাস

1

ফ্লোবকের উত্তরটি সঠিক সমাধান ছিল। অদ্ভুতভাবে, জিএনইউয়ের আউটপুট parallelম্যাঙ্গেল হয়ে যায় যদি এটি কোনও ফাইলে সরাসরি আউটপুট হয় - তবে এটি যদি টিটিটিতে যায় না।

ভাগ্যক্রমে, script -cএকটি tty নকল করার জন্য উপলব্ধ।

এখনও তিনটি স্ক্রিপ্ট আছে:

#!/bin/bash
# handle_1.sh
while true; do echo "1-$RANDOM$RANDOM$RANDOM$RANDOM"; done

#!/bin/bash
# handle_2.sh
while true; do echo "2-$RANDOM$RANDOM$RANDOM$RANDOM"; done

#!/bin/bash
# handle_3.sh
while true; do echo "3-$RANDOM$RANDOM$RANDOM$RANDOM"; done

তারপরে একটি ফাইল রয়েছে যা কলকে সমান্তরালে আবদ্ধ করে:

#!/bin/bash
# run_parallel.sh
parallel -u -I N ./handle_N.sh ::: "1" "2" "3"

এবং তারপরে আমি এটিকে এভাবে ডাকি:

script -c ./run_parallel > output

আউটপুটটিতে থাকা লাইনগুলি বিভিন্ন স্ক্রিপ্টগুলির আউটপুটের মধ্যে লাইন-লাইন মিশ্রিত হয় তবে তারা প্রদত্ত লাইনে ম্যাঙ্গেল বা ইন্টারলিভ হয় না।

উদ্ভট আচরণ থেকে parallel- আমি একটি বাগ রিপোর্ট ফাইল করতে পারি।

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