top
:
Linux console command listing all active processes C++98
C++11
/* compile with * g++ -std=c++11 -pthread test.cpp */ #include <iostream> #include <thread> #include <cmath> #define VARIABLE_NAME(x) #x using namespace std; const int globalN = 1000000; /* calculate the golden number through a continued fraction expansion */ void goldenN(string threadName) { cout << "subroutine " << __FUNCTION__ << "() launched by thread --" << threadName << "--\n\n"; int N = globalN; double goldenNumber = 1.0; for (int ii = 1; ii<N; ii++) { goldenNumber = 1.0+1.0/goldenNumber; if (ii%(N/10)==0) printf("goldenNumber: continued fraction (exact) %20.16f %20.16f\n",goldenNumber,(1.0+sqrt(5.0))/2.0); } // do stuff... } /* calculate exp(x) through a limit sequence */ void natural(double x, string threadName) { cout << "subroutine " << __FUNCTION__ << "() launched by thread --" << threadName << "--\n\n"; int N = globalN; double exponential = 1.0; for (int ii = 1; ii<N; ii++) { exponential = exponential*(1.0+x*1.0/N); if (ii%(N/10)==0) printf(" exponential: limit sequence (exact) %20.16f %20.16f\n",exponential,exp(x)); } printf(" exponential: limit sequence (exact) %20.16f %20.16f\n",exponential,exp(x)); } int main() { thread first(goldenN,VARIABLE_NAME(first)); // spawn new thread that calls goldenN() thread second(natural,1.0,VARIABLE_NAME(second)); // spawn new thread that calls natural(1.0) printf("\n main(); goldenN() and natural() now execute concurrently %d times..\n\n",globalN); // synchronize threads: first.join(); // pauses until first finishes second.join(); // pauses until second finishes printf("goldenN() and natural() completed.\n"); return 1; }
mutex
/* compile with * g++ -std=c++11 -pthread test.cpp * test by commenting out the mutex lock */ #include <iostream> // cout #include <thread> // thread #include <mutex> // mutex using namespace std; mutex mtx; // mutex for critical section void printBlock(int n, char c) { // critical section (exclusive access to cout signaled by locking mtx) // order of lines printed may vary, but characters are never mixed mtx.lock(); for (int i=0; i<n; ++i) cout << c; cout << '\n'; mtx.unlock(); } int main () { const int N =20; thread manyThreads[N]; // array of threads /* mtx.lock(); // testing (1) */ for (int i=0;i<N;i++) { manyThreads[i] = thread(printBlock,50,(char)(50+i)); } // for (int i=0;i<N;i++) manyThreads[i].join(); /* mtx.unlock(); // testing (1) */ return 0; }
chrono
: yet another (C++11) time facility
/* compile with * g++ -std=c++11 -pthread test.cpp */ #include <iostream> #include <thread> // C++11 threading #include <chrono> // C++11 times using namespace std; void justSleeping(int myNumber) { thread::id this_id = this_thread::get_id(); // every thread has its own id int cpuNumber = sched_getcpu(); // cout << "thread " << myNumber << " with id --" << this_id << "-- runs in " << __FUNCTION__ << "() on cpu # " << cpuNumber << endl; // this_thread::sleep_for(chrono::seconds(3)); // sleep_for() works with chrono } void doingStuff(int myNumber) { thread::id this_id = this_thread::get_id(); int cpuNumber = sched_getcpu(); // cout << "thread " << myNumber << " with id --" << this_id << "-- runs in " << __FUNCTION__ << "() on cpu # " << cpuNumber << endl; // double rr = 1.0; for (int ii = 1; ii<900000000; ii++) rr = 1.0+1.0/rr; } int main() { unsigned int nCPU = 1 * std::thread::hardware_concurrency(); printf("%d concurrent threads are supported.\n",nCPU); thread manyThreads[nCPU]; // array of threads // ------------------------- // starting time measurement (chrono:: for static functions in chrono) // ------------------------- chrono::time_point<chrono::system_clock> end, start = chrono::system_clock::now(); // ------------------------- for (int i=0;i<nCPU;i++) { // manyThreads[i] = thread(justSleeping,i); manyThreads[i] = thread(doingStuff,i); } // for (int i=0;i<nCPU;i++) manyThreads[i].join(); // // --------------------- // end time measurement // --------------------- end = chrono::system_clock::now(); chrono::duration<double> elapsed_seconds = end-start; time_t end_time = chrono::system_clock::to_time_t(end); // duration -- seconds cout << "finished computation at " << ctime(&end_time) << "elapsed time: " << elapsed_seconds.count() << "s\n"; // --------------------- }
fork()
instantiates a fully new process#include <stdio.h> #include <unistd.h> // fork() (linux), sleep() #include <sys/types.h> // getpid() (not univeral) using namespace std; int main() { const long bigNumber = 4000000000; double rr = 1.0; // variables valid for both processes // printf("# before creating a fork\n"); // the original process has an internal PID given by the system, // close to the one seen by 'top', the PID of the child is zero pid_t pid_of_first_fork = fork(); // pid_t pid_of_second_fork = fork(); printf("# after creating the second fork : %6d %6d | %6d\n", (int)pid_of_first_fork,(int)pid_of_second_fork,getpid()); // for (long ii = 1; ii<bigNumber; ii++) { rr = 1.0+1.0/rr; if (ii*2==bigNumber) if ((int)pid_of_first_fork==0) if ((int)pid_of_second_fork==0) printf("\n"); } // printf("# finishing now : %6d %6d\n",(int)pid_of_first_fork,(int)pid_of_second_fork); // if ((int)pid_of_first_fork>0) // parent process finshes last (just for prompt) if ((int)pid_of_second_fork>0) sleep(4); return 1; }
/* compile with * g++ -std=c++11 -pthread test.cpp */ #include <iostream> #include <iomanip> // IO manipulations #include <thread> // C++11 threading #include <chrono> // C++11 times #include <unistd.h> // fork() (linux), sleep() #include <sys/types.h> // getpid() (not univeral) using namespace std; void justSleeping(int myNumber) { thread::id this_id = this_thread::get_id(); // every thread has its own id int cpuNumber = sched_getcpu(); // cout << "thread " << myNumber << " with id --" << this_id << "-- runs " << __FUNCTION__ << "() on cpu # " << cpuNumber << endl; // this_thread::sleep_for(chrono::seconds(3)); // sleep_for() works with chrono } void doing__stuff(int myNumber) { thread::id this_id = this_thread::get_id(); int cpuNumber = sched_getcpu(); // cout << "thread " << myNumber << " with id --" << this_id << "-- runs " << __FUNCTION__ << "() on cpu # " << cpuNumber << endl; // double rr = 1.0; for (int ii = 1; ii<900000000; ii++) rr = 1.0+1.0/rr; } int main() { unsigned int nCPU = 1 * std::thread::hardware_concurrency(); printf("%d concurrent threads are supported.\n\n", nCPU); // thread manyThreads[nCPU]; // array of threads chrono::time_point<chrono::system_clock> end, // finishing time start = chrono::system_clock::now(); // staring time // ------------------------- // forking before threading // ------------------------- pid_t pid_of_fork = fork(); printf("# after creating the fork : %6d | %6d\n\n", (int)pid_of_fork, getpid()); // ------------------------- // threading // ------------------------- for (int i=0;i<nCPU;i++) { if (pid_of_fork==0) // inside child fork? manyThreads[i] = thread(justSleeping,i); else manyThreads[i] = thread(doing__stuff,i); this_thread::sleep_for(chrono::milliseconds(200)); } // if (pid_of_fork==0) // a delay of ten seconds sleep(10); // --------------------- // fork after threading // --------------------- pid_t pid_of_next_fork; if (pid_of_fork==0) pid_of_next_fork = fork(); thread::id thread_id; thread::id my_id = this_thread::get_id(); // id of current thread // for (int i=0;i<nCPU;i++) { thread_id = manyThreads[i].get_id(); // thread --> thread id // cout << setw(6) << getpid() << " " << setw(6) << pid_of_fork << " " << setw(6) << pid_of_next_fork << " " << i << " " << manyThreads[i].joinable() << " " << thread_id << " " << my_id << endl; // this_thread::sleep_for(chrono::milliseconds(200)); manyThreads[i].join(); } // // --------------------- // end time measurement // --------------------- end = chrono::system_clock::now(); chrono::duration<double> elapsed_seconds = end-start; time_t end_time = chrono::system_clock::to_time_t(end); // duration -- seconds // cout << "fork " << getpid() << " used "<< elapsed_seconds.count() << " seconds; timestamp :: " << ctime(&end_time) << "\n"; // --------------------- }
#pragma (..)
compiler specific pre-compiler directives
#pragma omp parallel for
threading with (oMP) of next for loop g++ -fopenmp test.cpp
where
-fopenmp enables openMP
/* compile and run with (look at real time used) * g++ -fopenmp test.cpp * time ./a.out 90000000 */ #include <iostream> // standard IO #include <stdio.h> // for printf #include <cstdlib> // for atof #include <math.h> // for the math #include <time.h> // ('clock()' measures time in nanoseconds) using namespace std; /* **************************************** */ /* ***** time in seconds ******* */ /* **************************************** */ double timeInSeconds() { const double oneSecond = 1.0 / CLOCKS_PER_SEC; static long int lastTime = clock(); long int actual_time = clock(); long int elapsed_time = actual_time - lastTime; lastTime = actual_time; return elapsed_time * oneSecond; // time passed since last call } /* **************************************** */ /* ***** main ******* */ /* **************************************** */ int main(int argLength, char* argValues[]) // parsing command line arguments { if (argLength==1) { cout << "please run with an integer argument (loop size)\n"; return 0; } long int loopSize = (long)(atof(argValues[1])); double *results = new double[loopSize]; int tenPerCent = int(loopSize/10.0); // timeInSeconds(); // initialized // #pragma omp parallel for // test with and without for (size_t i=0;i<loopSize;i++) { double rr = i*1.0/(1.0+i); results[i] = cos(cos(rr)); if ((i%tenPerCent)==0) printf(" %3.1f of loop completed\n", i*1.0/loopSize); } printf("time used: %8.4f (seconds)\n", timeInSeconds()); // return 1; }
system("command")
executes any (linux) command
renice
sets the priority of the program#include <stdio.h> #include <iostream> /* strings */ #include <unistd.h> /* fork (linux), sleep */ #include <sys/types.h> /* getpid() */ #include <stdlib.h> /* system, srand, rand */ #include <time.h> /* for the time */ using namespace std; int main(int argLength, char* argValues[]) // parsing command line arguments { srand( (unsigned)time( NULL ) ); // initializing the random number const double oneSecond = 1.0 / CLOCKS_PER_SEC; long starting_time = clock(); int myPID = getpid(); printf("\n"); printf("# I am the process %d\n",myPID); // // --- renice the actual process // int myNice =(rand()%20); // renice [0:19], only higer values (lower prriority) allowed char reniceString[66]; // array of char for the renice string sprintf(reniceString, "renice %d -p %d",myNice,myPID); printf("%s\n",reniceString); system(reniceString); // sytem call : renice // // --- do stuff // const long bigNumber = 1000000000; double rr = 1.0; // variables valid for both processes for (long ii = 1; ii<bigNumber; ii++) rr = 1.0+1.0/rr; // // --- finish and continue // printf("finishing; priority, time : %2d %10.2f seconds\n",myNice,(clock()-starting_time)*oneSecond); system(argValues[0]); // system call : start next program; system("./a.out") return 1; }
gnuplot
-persist : the gnuplot window persists$data << EOD 1 5 2 10 3 1 EOD plot "$data" w linesp
popen()
executes a command and pipes the
executed command /* using gnuplot directly from C++ * by writing to gnuplot via a pipe (stream) created by popen() * the data is stored inline in gnuplot as data blocks */ #include <iostream> #include <sstream> #include <stdio.h> #include <cstdlib> #include <math.h> using namespace std; // === // === (x,y) string for inline data input for gnuplot // === the data block created has the name 'dataName' // === string xyValuesGnu(double xValues[],double yValues[],int nData, string dataName) { stringstream ss; ss << dataName << " << " << "EOD\n"; // defining data block for (int i=0;i<nData;i++) ss << xValues[i] << " " << yValues[i] << endl; ss << "EOD\n"; // terminating data block // return ss.str(); } // === // === create some nice data // === void createData(double xValues[],double yValues[],int nData,double width,double omega,double r0) { double angle, radius; for (int i=0;i<nData;i++) { angle = i*M_PI*2.0/nData; radius = width*sin(omega*angle) + r0; xValues[i] = radius*cos(angle); yValues[i] = radius*sin(angle); } } int main() { const int nData = 400; string dataToPlot, dataName; double x[nData]; double y[nData]; FILE *pipeGnu = popen("gnuplot -persist", "w"); // streaming to gnuplot // first curve dataName = "$data_1"; createData(x,y,nData,3.0,9.0,1.0); // create some data dataToPlot = xyValuesGnu(x,y,nData,dataName); // data to string fprintf(pipeGnu, "%s\n",dataToPlot.c_str()); // input data block fprintf(pipeGnu, "plot \"%s\" w lines lw 3\n",dataName.c_str()); // plot the data block fflush(pipeGnu); // second curve dataName = "$data_2"; createData(x,y,nData,2.0,11.0,3.0); // create some data dataToPlot = xyValuesGnu(x,y,nData,dataName); // data to string fprintf(pipeGnu, "%s\n",dataToPlot.c_str()); // input data block fprintf(pipeGnu, "replot \"%s\" w lines lw 3\n",dataName.c_str()); // plot the data block fflush(pipeGnu); fclose(pipeGnu); // closing the pipe to gnuplot return 1; }
set term gif animate
for creating an animated gif /* animation by using gnuplot directly from C++ * by writing to gnuplot via a pipe (stream) created by popen() * the data is stored inline in gnuplot as data blocks */ #include <iostream> #include <sstream> #include <stdio.h> #include <cstdlib> #include <math.h> #include <unistd.h> using namespace std; // === // === (x,y) string for inline data input for gnuplot // === the data block created has the name 'dataName' // === string xyValuesGnu(double xValues[],double yValues[],int nData, string dataName) { stringstream ss; ss << dataName << " << " << "EOD\n"; // defining data block for (int i=0;i<nData;i++) ss << xValues[i] << " " << yValues[i] << endl; ss << "EOD\n"; // terminating data block // return ss.str(); } // === // === create some nice data // === void createData(double xValues[],double yValues[],int nData,double r0,double a0, double r1) { double angle, radius; double x0 = r0*cos(a0); double y0 = r0*sin(a0); for (int i=0;i<nData;i++) { angle = i*M_PI*2.0/(nData-1.0); xValues[i] = x0 + r1*cos(angle); yValues[i] = y0 + r1*sin(angle); } } int main() { const int nData = 100; const int nAnim = 500; string dataToPlot; string dataName = "$dataAnim"; double x[nData]; double y[nData]; FILE *pipeGnu = popen("gnuplot", "w"); // streaming to gnuplot // starting if (1==2) // option for animated gif { fprintf(pipeGnu, "reset\n"); fprintf(pipeGnu, "set term gif animate\n"); fprintf(pipeGnu, "set output \"animate.gif\"\n"); } // fprintf(pipeGnu, "set xrange [-5:5]\n"); fprintf(pipeGnu, "set yrange [-5:5]\n"); // for (int iAnim=0;iAnim<nAnim;iAnim++) { double changingAngle = iAnim*10*M_PI/nAnim; createData(x,y,nData,2.5,changingAngle,2); dataToPlot = xyValuesGnu(x,y,nData,dataName); // data to string fprintf(pipeGnu, "%s\n",dataToPlot.c_str()); // change data block // if (iAnim==0) fprintf(pipeGnu, "plot \"%s\" w lines lw 10\n",dataName.c_str()); // plot the data block else fprintf(pipeGnu, "replot\n"); // replot // fflush(pipeGnu); usleep(20000); // sleep for microseconds } fclose(pipeGnu); // closing the pipe to gnuplot return 1; }