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