วิธีรันกระบวนการแบบขนานและรวมเอาต์พุตเมื่อทั้งคู่เสร็จสิ้น


17

ฉันมีสคริปต์ทุบตีเปลือกที่ฉันท่อข้อมูลบางอย่างผ่านประมาณ 5 หรือ 6 โปรแกรมที่แตกต่างกันแล้วผลสุดท้ายเป็นไฟล์ที่คั่นด้วยแท็บ

ฉันจะทำเช่นเดียวกันอีกครั้งสำหรับชุดข้อมูลที่คล้ายกันและส่งออกไปยังไฟล์ที่สอง

จากนั้นไฟล์ทั้งสองจะถูกป้อนเข้าสู่โปรแกรมอื่นสำหรับการวิเคราะห์เปรียบเทียบ เช่นเพื่อลดความซับซ้อน

Data1 | this | that |theother | grep |sed | awk |whatever > Data1Res.csv
Data2 | this | that |theother | grep |sed | awk |whatever > Data2Res.csv
AnalysisProg -i Data1res.csv Data2res.csv

คำถามของฉันคือฉันจะทำให้ขั้นตอนที่ 1 และขั้นที่ 2 ในเวลาเดียวกัน (เช่นการใช้ &) แต่เปิดตัวเพียงขั้นตอนที่ 3 (AnalysisProg) เมื่อทั้งสองเสร็จสมบูรณ์?

ขอบคุณ

ps AnalysisProg จะไม่ทำงานบนสตรีมหรือ Fifo


ตรวจสอบสิ่งนี้: pebblesinthesand.wordpress.com/2008/05/22/…
Bichoy

BTW คุณสามารถใช้สคริปต์ Perl ได้หรือไม่? สิ่งนี้สามารถลดความซับซ้อนของเรื่องได้มากมายสำหรับคุณและคุณสามารถใช้การโพสต์การประมวลผลอย่างมีประสิทธิภาพมากและทำให้มันทำงานแบบขนานได้อย่างง่ายดาย
Bichoy

Perl .. ไม่มากไม่มี :(
Stephen Henderson

1
ที่นี่ฉันสาธิตวิธีแยกอินพุตข้ามไพพ์ด้วยteeและประมวลผลด้วยสองgrepกระบวนการพร้อมกัน: unix.stackexchange.com/questions/120333/…
mikeserv

และที่นี่ฉันแสดงให้เห็นถึงวิธีการใช้เชลล์แบบง่าย ๆ เพื่อสร้างพื้นฐานกระบวนการในแบบที่nohupอาจ แต่ยังคงมีวิธีการสื่อสารกับกระบวนการ: unix.stackexchange.com/questions/121253/ …
mikeserv

คำตอบ:


27

waitใช้ ตัวอย่างเช่น:

Data1 ... > Data1Res.csv &
Data2 ... > Data2Res.csv &
wait
AnalysisProg

จะ:

  • เรียกใช้ Data1 และ Data2 ไพพ์เป็นงานพื้นหลัง
  • รอให้ทั้งคู่เสร็จสิ้น
  • เรียกใช้ AnalysisProg

ดูเช่นคำถามนี้


ขอบคุณที่ดูดี ฉันจะลองดูถ้าข้างต้นไม่ทำงาน
สตีเฟ่นเฮนเดอร์สัน

ขอบคุณอีกครั้งฉันก็ตระหนักถึงการรอ แต่มี googled เล็กน้อยก็สับสนกับวิธีการทำงานกับ PID ที่แตกต่างกัน ฯลฯ ฉันรู้สึกงงตอนนี้ฉันเห็นว่ามันเป็นเพียง "รอ"
สตีเฟ่นเฮนเดอร์สัน

12

คำตอบของ cxw ไม่ต้องสงสัยเลยว่าทางออกที่ดีกว่าคือถ้าคุณมี 2 ไฟล์เท่านั้น หากทั้ง 2 ไฟล์เป็นเพียงตัวอย่างและในความเป็นจริงคุณมี 10,000 ไฟล์การแก้ปัญหา '&' จะไม่ทำงานเนื่องจากจะทำให้เซิร์ฟเวอร์ของคุณโอเวอร์โหลด สำหรับสิ่งที่คุณต้องการเครื่องมือเช่น GNU Parallel:

ls Data* | parallel 'cat {} | this | that |theother | grep |sed | awk |whatever > {}res.csv
AnalysisProg -i *res.csv

หากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับ GNU Parallel:

  • ชมวิดีโอแนะนำสำหรับการแนะนำอย่างรวดเร็ว: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
  • เดินผ่านบทช่วยสอน (ผู้ชาย parallel_tutorial) บรรทัดคำสั่งของคุณจะรักคุณ

สวัสดีขอบคุณ ในเวลานี้ฉันมีไฟล์สองไฟล์ แต่ฉันมีโปรเซสเซอร์ 24 ตัวดังนั้นฉันจึงรู้สึกอยากลองและรันหลาย ๆ คู่พร้อมกัน - แม้ว่าจะไม่ใช่คนวิทยาศาสตร์คอมพิวเตอร์ฉันก็ไม่แน่ใจว่าคอขวดที่อ่านได้จะคุ้มค่าหรือไม่ บางทีฉันอาจจะดูดมันและดู;)
สตีเฟ่นเฮนเดอร์สัน

@StephenHenderson ขึ้นอยู่กับขนาดของไฟล์ที่สามารถอยู่ในแคช หากความเร็วสำคัญคุณสามารถใช้ tmpfs (และไฟล์นั้นเป็น <<< จากนั้น RAM ของคุณ)
Maciej Piechotka

1
@StephenHenderson จำนวนงานขนานสามารถปรับได้ด้วย -j ดังนั้นลอง -j4 และหากเซิร์ฟเวอร์ไม่ทำงานเกินลอง -j6 เป็นต้น แต่พร้อมกด CTRL-C: GNU Parallel เป็นเครื่องมือที่ยอดเยี่ยมสำหรับการโหลดเซิร์ฟเวอร์มากเกินไปอย่างรวดเร็ว . ยังได้ดู - โหลด
Ole Tange

1

วิธีหนึ่งในการทำเช่นนี้อาจมีลักษณะดังนี้:

AnalysisProg <<PREPROCESS /dev/stdin
$( 
{   process1=$( pipe | line | 1 >&2 & echo $! )
    process2=$( pipe | line | 2 >&2 & echo $! )
    while ps -p $process1 $process2 >/dev/null; do
        sleep 1
    done
} 2>&1
)
#END
PREPROCESS

ด้วยวิธีนี้คุณใช้แบ็คกราวน์ทั้งสอง แต่ยังคงรอให้การดำเนินการเสร็จสิ้นก่อนที่จะรวมเอาท์พุทของพวกเขาเป็น stdin ซึ่งได้รับการประเมินในเอกสารที่นี่แล้วส่งมอบให้กับ AnalysisProg หากคุณสามารถใช้waitสิ่งนี้ดีกว่าwhile psลูป แต่เชลล์ขึ้นอยู่กับว่าwaitสามารถคัดค้านหากคุณสั่งให้รอในกระบวนการที่ไม่ใช่ลูกของเชลล์ปัจจุบัน

นอกจากนี้โปรดทราบว่าวิธีการด้านบนจะตรวจสอบผลลัพธ์ - ดังนั้นกระบวนการทั้งสองจะเขียนออกมาทันที หากคุณต้องการให้พวกเขาแยกจากกันหรือต่อท้ายซึ่งกันและกันคุณอาจทำ:

AnalysisProg 3<<PREPROCESS /dev/fd/3 /dev/stderr
$(
process1=$(... >&2 ...) 2>/dev/fd/3
...
} 3>/dev/fd/3 2>/dev/stderr
)

ฉันได้แสดงแนวคิดเหล่านี้มาก่อน น่าจะเป็นประชาชนที่ดีที่สุดคือที่นี่และที่นี่


0

ลองใช้สิ่งนี้

rm -f Data1Res.csv
rm -f Data2Res.csv
Data1 | this | that |theother | grep |sed | awk |whatever > Data1Res.csv &
Data2 | this | that |theother | grep |sed | awk |whatever > Data2Res.csv &
while true
do
  ps aux | grep -v grep | grep -i -E 'Data1Res.csv|Data2Res.csv' &> /dev/null
  if [ $? -ne 0 ]
  then
    AnalysisProg -i Data1res.csv Data2res.csv
    exit 0
  fi
done

นั่นเป็นสิ่งที่หนัก มันไม่เหมือนการสร้างwaitวงล้อใหม่เหรอ?
John WH Smith
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.