Как к командам выполнения в оболочке параллельно, не разрушая вывод?

У меня есть следующий сценарий оболочки:

./run 50 5000 100 100 1.0 2 0.3 0.3 0.05 1 101 0 2 1 0 10 0.1 &
./run 50 5000 100 100 1.0 2 0.3 0.3 0.05 1 101 0 2 1 0 10 0.2 &
./run 50 5000 100 100 1.0 2 0.3 0.3 0.05 1 101 0 2 1 0 10 0.5 &
./run 50 5000 100 100 1.0 2 0.3 0.3 0.05 1 101 0 2 1 0 10 1 &
./run 50 5000 100 100 1.0 2 0.3 0.3 0.05 1 101 0 2 1 0 25 0.1 &
./run 50 5000 100 100 1.0 2 0.3 0.3 0.05 1 101 0 2 1 0 25 0.2 &
./run 50 5000 100 100 1.0 2 0.3 0.3 0.05 1 101 0 2 1 0 25 0.5 &
./run 50 5000 100 100 1.0 2 0.3 0.3 0.05 1 101 0 2 1 0 25 1 &
./run 50 5000 100 100 1.0 2 0.3 0.3 0.05 1 101 0 2 2 0 10 0.1 &
./run 50 5000 100 100 1.0 2 0.3 0.3 0.05 1 101 0 2 2 0 10 0.2 &
./run 50 5000 100 100 1.0 2 0.3 0.3 0.05 1 101 0 2 2 0 10 0.5 &
./run 50 5000 100 100 1.0 2 0.3 0.3 0.05 1 101 0 2 2 0 10 1 

И моя основная функция имеет структуру как это:

int main(int argc, char** argv)
{
    if(argc<18)
    {
        cout<<"Insufficient parameters"<<endl;
        cout<<"loop #ofGen popSize chrLen Pc PmNumerator randPopRate BOAimmigrantsRate Pn algoType #ofBOAsamples mkpfileNo noiseType prb env per sev"<<endl;
        exit(1);
    }

    int algoType;// GA or PBIL
    int mkpfile;
    loop = atoi(argv[1]);
    GA.generation = atoi(argv[2]);
    GA.popSize = atoi(argv[3]);
    GA.chromosomeLength = atoi(argv[4]);
    GA.Pc = atof(argv[5]);
    GA.PmNumerator = atoi(argv[6]);
    GA.randomPopulationRate = atof(argv[7]);
    GA.ImmigrantRateFromBOA = atof(argv[8]);
    DE.Pn = atof(argv[9]);
    algoType = atoi(argv[10]);
    CM.numOfSamples = atoi(argv[11]);
    mkpfile=atoi(argv[12]);
    DE.noiseType=atoi(argv[13]);
    DE.problemType=atoi(argv[14]);
    DE.environmentType = atoi(argv[15]);
    DE.period=atoi(argv[16]);
    DE.severity=atof(argv[17]);

    printf("\nRunning... Problem type: %d...",DE.problemType);
    fflush(stdout);
    for(int i=1; i<=loop; i++)
    {
        myAlgorithm(i,DE.problemType,algoType,mkpfile);
    }
    cout<<"Done!"<<endl;
    return 0;
}

Когда я выполняю вышеупомянутый код, я хочу вывод к первой печати printf() часть, которая не имеет вещи новой строки и затем печатает cout часть:

Running bla bla bla... Done!

Это работает правильно, если я выполняю только один тестовый сценарий, однако когда я использую сценарий оболочки для выполнения больше чем одного тестового сценария параллельно, это становится как это:

    Running... Problem type: 1...Running... Problem type: 1...
Running... Problem type: 1...
Running... Problem type: 1...
Running... Problem type: 1...
Running... Problem type: 1...
Running... Problem type: 1...
Running... Problem type: 1...
Running... Problem type: 2...
Running... Problem type: 2...
Running... Problem type: 2...
Running... Problem type: 2...Done!
Done!
Done!

Running... Problem type: 2...
Running... Problem type: 2...
Running... Problem type: 3...
Running... Problem type: 3...
Running... Problem type: 3...
Running... Problem type: 3...
Running... Problem type: 2...
Running... Problem type: 3...
Running... Problem type: 3...

Running... Problem type: 2...Running... Problem type: 3...
Running... Problem type: 3...Done!
Done!
Done!
Done!
Done!
Done!
Done!
Done!
Done!
Done!
Done!

Там путь состоит в том, чтобы сделать, которые происходят правильно? Я спрашиваю это здесь, так как я думаю, что это - связанная с Ubuntu проблема.

3
задан 21 February 2019 в 12:47

2 ответа

Встретьте GNU parallel Install parallel (sudo apt install parallel):

Параллель GNU является инструментом оболочки для выполнения заданий в параллели с помощью одного или нескольких компьютеров. (…) [Это] удостоверяется, что вывод от команд является тем же выводом, как Вы сделать Вас выполнить команды последовательно. (man parallel)

В Вашем случае с повторяющимися аргументами можно использовать bash Расширение фигурной скобки для легкого создания командных строк. Базовый синтаксис parallel COMMAND {} ::: ARGUMENTS, если Вы хотите дать каждый шанс, несколько аргументов заботятся о надлежащем заключении в кавычки для предотвращения разделения слова, например:

$ parallel echo ./run some args {} ::: {"1 0 "{10,25},"2 0 10"}\ {0.{1,2,5},1}
./run some args 1 0 10 0.1
./run some args 1 0 10 0.2
./run some args 1 0 10 0.5
./run some args 1 0 10 1
./run some args 1 0 25 0.1
./run some args 1 0 25 0.2
./run some args 1 0 25 0.5
./run some args 1 0 25 1
./run some args 2 0 10 0.1
./run some args 2 0 10 0.2
./run some args 2 0 10 0.5
./run some args 2 0 10 1
2
ответ дан 1 December 2019 в 15:49

Ваш вывод сценария не будет смешан при перенаправлении вывода каждой команды в различный файл. Например:

./run 50 5000 100 100 1.0 2 0.3 0.3 0.05 1 101 0 2 1 0 10 0.1 > run-0.1.log &
./run 50 5000 100 100 1.0 2 0.3 0.3 0.05 1 101 0 2 1 0 10 0.2 > run-0.2.log &
./run 50 5000 100 100 1.0 2 0.3 0.3 0.05 1 101 0 2 1 0 10 0.5 > run-0.5.log &
./run 50 5000 100 100 1.0 2 0.3 0.3 0.05 1 101 0 2 1 0 10 1 > run-1.0.log &

Можно позже открыть эти файлы и проверить детали каждого процесса.

Или, если Вы не интересуетесь наблюдением выводов вообще, перенаправляете их к /dev/null.

2
ответ дан 1 December 2019 в 15:49

Другие вопросы по тегам:

Похожие вопросы: