Параллельный запуск и ожидание процессов от подоболочки - PullRequest
0 голосов
/ 14 июля 2020

Привет всем / Я пытаюсь сделать что-то вроде parallel tool для оболочки просто потому, что функциональности parallel недостаточно для моей задачи. Причина в том, что мне нужно запускать разные версии компилятора. Представьте, что мне нужно скомпилировать 12 программ с разными компиляторами, но я могу запустить только 4 из них одновременно (иначе P C исчерпает память и вылетит :). Я также хочу иметь возможность наблюдать, что происходит с каждой компиляцией, поэтому я выполняю каждую компиляцию в новом окне. Чтобы упростить задачу, я заменю запускаемый мной компилятор небольшим скриптом, который ждет и возвращает идентификатор процесса sleep. sh:

#!/bin/bash
sleep 30 
echo $$

Итак, основной скрипт должен выглядеть как parallel_run. sh:

#!/bin/bash
for i in {0..11}; do
  xfce4-terminal -H -e "./sleep.sh" &
  pids[$i]=$!
  pstree -p $pids
  if (( $i % 4 == 0 ))
  then
    for pid in ${pids[*]}; do 
      wait $pid
    done
  fi
done

Проблема в том, что с $! Я получаю pid xfce4-terminal, а не программу, которую он выполняет. Итак, если я посмотрю на ptree 1-й итерации, я могу увидеть вывод основного скрипта:

xfce4-terminal(31666)----{xfce4-terminal}(31668)
                      |--{xfce4-terminal}(31669)

и sleep. sh говорит, что у него было pid = 30876 в то время. Таким образом, ожидание в этом случае вообще не работает.

Q: Как получить правильный PID компилятора, который работает в подоболочке? Может, есть другой способ решить такую ​​задачу?

1 Ответ

0 голосов
/ 15 июля 2020

Похоже, что нет способа отследить PID от родителя к потомку, если вы вызываете процесс в новом xfce4-терминале, поскольку процесс терминала умирает сразу после выполнения данной команды. Итак, я пришел к решению, которое не идеально, но приемлемо в моей ситуации. Я запускаю и помещаю процессы компилятора в фоновый режим и перенаправляю вывод в файл .log. Затем я запускаю tail в этих файлах журнала и убиваю все хвосты, принадлежащие текущему $ USER, когда компиляторы из текущего пакета завершены, затем я запускаю другой пакет.

#!/bin/bash
for i in {1..8}; do
  ./sleep.sh > ./process_$i.log &
  prcid=$!
  xfce4-terminal -e "tail -f ./process_$i.log" &
  pids[$i]=$prcid
  if (( $i % 4 == 0 ))
  then
    for pid in ${pids[*]}; do 
      wait $pid
    done
  killall -u $USER tail
  fi
done

Надеюсь, что есть не будет других хвостов запущенных в это время :)

...