Çıktıyı kesmeden kabuktaki komutlar paralel olarak nasıl çalıştırılır?


3

Aşağıdaki kabuk betiğine sahibim:

./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 

Ve ana fonksiyonum şöyle bir yapıya sahip:

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;
}

Yukarıdaki kodu çalıştırdığımda, çıktının önce printf()newline olmayan bir coutbölümü yazdırmasını ve ardından bölümü yazdırmasını istiyorum :

Running bla bla bla... Done!

Yalnızca bir test senaryosunu çalıştırdığımda doğru çalışır, ancak birden fazla test senaryosunu paralel olarak çalıştırmak için shell komut dosyasını kullandığımda şöyle olur:

    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!

Bunu doğru şekilde yapmanın yolu var mı? Ubuntu ile ilgili bir sorun olduğunu düşündüğümden beri burada soruyorum.


2
Bu soru, yığın taşması (?) İçin söylenenden daha uygun olabilir (bir uzmandan uzak olduğum için yanılıyorsam birisinin beni düzelteceğine eminim ...) ama stdout’a kızmak istediğinden emin misin? sonra printf(Running...)mı? IIRC hemen ateş basması için yazdırır stdoutveya yazdırdığınız her yerde, hemen yazdırmak böylece başka örneği paralel olarak çalıştığında o zaman yazdırmak olduğunu anında döngü bitirmek için önceki örneği için beklemeden
j-para

1
Bu beklenen bir davranış. Arka planda çalışan (veya yazarken paralel olarak çalışan) her işlem, kodun dediğini söylediğinde çıkar. Ve işaretlerini komut dosyasından kaldırırsanız, ./runişlemler her seferinde birer çalışır ve çıktı doğru sırada olur.
Soren

@ j-money OP kabuk komutlarını çalıştırırken nasıl düzgün çıktı siparişi alınacağını sorar, bence SO için uygun değil.
tatlı

Yanıtlar:


2

GNUparallel Paralel yüklemek ( sudo apt install parallel) ile tanışın :

GNU paralel, işleri bir veya daha fazla bilgisayar kullanarak paralel olarak yürütmek için kullanılan bir kabuk aracıdır. (…) [Bu] komutlardan gelen çıkışın, komutları sırayla çalıştırmanızın alacağı çıktıyla aynı olmasını sağlar. ( man parallel)

Tekrarlayan argümanlarla durumunda , komut satırlarını kolayca oluşturmak için bashBrace Expansion'ı kullanabilirsiniz . Temel sözdizimi parallel COMMAND {} ::: ARGUMENTS, eğer her koşuya birden fazla argüman vermek istiyorsanız, kelimelerin bölünmesini önlemek için uygun alıntılara dikkat edin , örneğin:

$ 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

Hey @ tatlım umarım oradasın. Bu komutu çalıştırdığımda, "yetersiz parametreler" yazıyor (yukarıdaki koda bakın). parallel ./run 4 50 5000 100 100 1 5 0 0 0.05 1 101 6 2 {} ::: {1,2,3,4}\ {0,1,2}\ {10,25}\ {0.{1,2,5},1}. Bence tartışmaları kabul etmiyor. Ne yapmalıyım?
WhoCares

@WhoCares burada neye ihtiyacınız olduğunu söylemek zor, ancak genel echoolarak genişlemenin sonuçlarını görmek ve sorunu takip edebilmek için cevabımdaki gibi bir ekleme yapın . Beni genel sohbet odasında buluyorsun .
tatlı

2

Her komutun çıktısını farklı bir dosyaya yönlendirirseniz, kod çıktınız birbirine karışmaz. Örneğin:

./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 &

Daha sonra bu dosyaları açabilir ve her işlemin ayrıntılarını kontrol edebilirsiniz.

Veya çıktıları hiç görmek istemiyorsanız, yönlendirin /dev/null.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.