2

Я пытаюсь найти решение относительно возможности одновременного запуска существующих исполняемых файлов. До сих пор я пришел к созданию оболочки, которая помещает указанный исполняемый файл в очередь (управляется «сервером»). Проблема в том, что мне нужно запустить несколько исполняемых файлов, выход которых является исполняемым входом другого.Общий способ одновременного запуска существующих исполняемых файлов

Пример:

У меня есть исполняемый файл выход которого файл (изображение). У меня есть еще один исполняемый B чей вход список файлов (считают это создает эскизы из качества снимков «s, сохраняет их в архив и т.д.)

Возникает вопрос: есть ли способ сделать B исполняемый файл ждет нескольких A Процессы для завершения?

Есть ли стандартный способ сделать это? Меня интересует концепция, и если это возможно, а не язык. Было бы неплохо, если бы решение было кросс-платформой, но на данный момент у меня нет никаких решений, поэтому не стесняйтесь делиться своими идеями. Я предполагаю, что это будет как-то сделано в C/C++, поскольку для этого требуется некоторое взаимодействие на низком уровне.

УПРОЩЕННЫЙ:


У меня есть несколько исполняемых файлов () работает в фоновом режиме и другой исполняемый файл (B), который использует свой выходной сигнал в качестве входных данных. Как заблокировать выполнение B, пока не будут доступны все необходимые входные файлы.

Примечание: исполняемые файлы непрерывно работать на машине, но некоторые из входных файлов «собраны» периодически B.


Спасибо за любые предложения,

Юлиан

+0

Существует несколько методов, которые могут использоваться для межпроцессного взаимодействия. [Вот несколько.] (Http: //en.wikipedia.org/wiki/Inter-process_communication) –

+0

@RobertHarvey Я согласен с IPC (я использую это), но представьте, что я запускаю все асинхронно через упомянутый «сервер», а в то время как исполняемый файл ** B ** запускается другими ** A ** исполняются исполняемые файлы. Проблема заключается в том, как мне «блокировать» ** B ** выполнять до тех пор, пока не будут выполнены все входные файлы? – INS

+0

** B ** ожидает, пока он не получит сигнал от каждого из дочерних процессов. –

ответ

1

Если вы говорите о программе, которая делает это для вас, GNU Parallel сделает это за вас. Вы можете настроить его на выполнение задания cron или, как вам кажется, нужным. Мы часто запускаем его из сценариев, чтобы переписать большой объем текста (или кода) и полностью использовать все ядра машины для выполнения этой работы. Часто вы можете использовать Parallel вместе со скриптами и sed/awk, чтобы получить то, что вам действительно нужно сделать. Я не совсем понимаю, если вы хотите сделать это программно, однако, возможно, это не лучший ответ.

+0

Выполнение исполняемых файлов параллельно - это проблема. Но другой проблемой является синхронизация - знать, когда все «зависимые» задачи завершили свою фазу обработки. ---> гарантируется существование выходных файлов ----> мы можем выполнить двоичный файл в зависимости от выходных файлов. – INS

+2

Это то, что делает инструмент make на самом деле. Это универсальный инструмент, который нельзя использовать для компиляции исходного кода. корректно определите свои зависимости и сделайте -j10 будет работать до 10 процессов параллельно, когда это возможно, а зависимые объекты будут запускаться, когда они будут завершены. Если это так же просто, как 1 процесс ожидания для нескольких других процессов, простой сценарий оболочки будет делать: 'for i в $ (seq 10); сделать ./A & done wait; ./B' – nos

+0

@nos да, я знаю о make, но в моем случае каждый исполняемый файл заканчивается мгновенно (выполняется в фоновом режиме), и я не знаю, когда файлы доступны. Как я уже упоминал: я не могу дождаться всех процессов, потому что другие исполняемые файлы ** ** не создают файлы, используемые для ввода ** B ** ... – INS

0

Обычный подход заключается в использовании примитивов синхронизации, например. семафоров или барьеров. Однако это зависит не только от языка, но и требует взаимодействия с платой (как правило, ОС).

Однако стандарт C++ 11 развертывает стандартизованную модель потоков на уровне библиотеки.

+0

это не про потоки -> Я запускаю существующие исполняемые файлы .. проблема в том, что вход будет доступен. – INS

+0

Это именно то, о чем речь. Нити - это легкие процессы, вы требуете «реальных» процессов, но принцип тот же. Используйте семафоры или что-то в этом роде. – Matthias

0

Я думаю, что способ сделать это - создать дерево зависимостей, где дочерние узлы зависят от выходов родительских узлов. Затем вы можете запускать каждый уровень своего дерева параллельно.

Например:

выход P1 идет на P2 и P3

выход P2 идет на Р4

выход P3 идет на P4.

Тогда ваше дерево выглядит следующим образом:

     P1 
        /\ 
        P2 P3 
        \/
        P4 

Вы должны запустить P1 первый, P2 и P3 могут работать параллельно, а затем P4 запускается на выполнение последней.

Также он не должен быть C++, любой старый язык будет делать трюк я уверен

EDIT: Если вы не знаете, когда предыдущая работа заканчивается, чтобы начать следующий вы можете установить цикл, который в каждый промежуток времени проходит через все исполняемые файлы, которые вы хотите запустить, и проверяет, что файлы, в которых они нуждаются, создаются, если они запускаются, в противном случае дождитесь следующей итерации и снова проверьте.

общая идея (в C++) может пойти что-то вроде:

struct Job 
    { 
     bool PreconditionsSatisfied(); 
     void Run(); 
    }; 

    std::vector<Job> jobs; 

    //Fill up with appropriate info 

    while(jobs.size() != 0) 
     { 
     for(int i = 0; i < jobs.size(); i++) 
      { 
      if(jobs[i].PreconditionsSatisfied()) 
       { 
       //start new thread and run job 
       jobs.erase(jobs.begin() + i); 
       i--; 
       } 
      } 
     sleep(TIME_INTERVAL); 
     } 
+0

да, это именно то, что я пытаюсь сделать. К сожалению, в моем случае P2 & P3 выполняются параллельно (асинхронно), а P4 не знает, когда их выход существует и запускается до того, как это произойдет ---> ошибка. Я выполняю асинхронно, потому что это быстрее ... – INS

1

Вы, наверное, не нужно ничего писать:

whenjobs является заменой хрон, который не только позволяет определить рабочие места (потенциально повторяющиеся), но также учитывает зависимости от работы:

0

Люди обычно используют make (или другие инструменты для сборки) для достижения этого, потому что это именно то, что делают эти инструменты: создавать вещи на основе входов с зависимостями и большинство - конечно make - может сделать это параллельно. Если у вас есть исполняемый файл, который создает серию изображений из (скажем) файлов данных, и у вас есть две партии из них для обработки (например, добавив их друг к другу), и вам придется запускать второй исполняемый файл в каждой партии отдельно, то следующий Makefile

execA=./gnuplotwrapper 
execB=convert 

all: figure1.png figure2.png 

# convert txt files to png files using a gnuplot script "gnuplotwrapper" 

%.png: %.txt 
    $(execA) $^ [email protected] 

# take two figures and append them using imagemagick's "convert" 

figure1.png: data1.png data2.png 
    $(execB) $^ +append [email protected] 

figure2.png: data3.png data4.png 
    $(execB) $^ +append [email protected] 

clean: 
    rm -f *.png 

будет использовать исполняемый A, чтобы генерировать файлы изображений из файлов данных и исполняемые в для обработки партий файлов изображений. Запустив это с помощью (скажем) make -j 4, make попытается использовать до 4 процессов параллельно, чтобы построить окончательный результат (здесь, figure1.png и figure2.png).

0

Если вам нужно запустить различные исполняемые файлы в системе, я считаю, что самым чистым решением является использование scheduler. Slurm или TORQUE должны быть приятным выбором.

Кроме того, конкретная функция, о которой вы просили, иногда упоминается как многоэтапное планирование заданий. Если он не поддерживается инициатором, довольно легко добиться того же результата с серией заданий, которые в случае успеха подадут их продолжение.