PhoenixThread  1.0.0
Tools to ease parallel programming in C++
Loading...
Searching...
No Matches
PMultiThreadProgress.cpp
Go to the documentation of this file.
1/***************************************
2 Auteur : Pierre Aubert
3 Mail : pierre.aubert@lapp.in2p3.fr
4 Licence : CeCILL-C
5****************************************/
6
7#include <sys/ioctl.h>
8#include <sstream>
9#include <iostream>
10
12
14
17void phoenix_print_parallel_progress(PMultiThreadProgress & progress, int refreshSecond){
18 while(!progress.isFinished()){ //While computation is ongoing
19 progress.print();
20 std::this_thread::sleep_for(std::chrono::seconds(refreshSecond)); //We check status of computation each second
21 }
22 progress.printSummary();
23 std::cout << "PMultiThreadProgress : Done" << std::endl;
24}
25
27
29PMultiThreadProgress::PMultiThreadProgress(size_t nbExpectedProgressBar){
30 initialisationPMultiThreadProgress(nbExpectedProgressBar);
31}
32
34
39
44
46
53
55
57void PMultiThreadProgress::setNbExpectedProgressBar(size_t nbExpectedProgressBar){
58 p_nbExpectedProgressBar = nbExpectedProgressBar;
59}
60
62
66size_t PMultiThreadProgress::addProgressBar(const PString & name, int progressMax){
67 std::lock_guard<std::mutex> guard(p_currentMutex);
68 size_t index = p_vecProgressElement.size();
70 el.progress = 0;
71 el.prevProgress = -1;
72 el.progressMax = progressMax;
73 el.name = name;
74 el.isEndError = false;
75 p_vecProgressElement.push_back(el);
76 return index;
77}
78
80
83 p_vecProgressElement[index].progress++;
84}
85
87
90 p_vecProgressElement[index].isEndError = true;
91}
92
94
99
102 if(!isModified()){return;} //No need to print
103 size_t nbColTerminal = getNbColTerminal();
104 //Clear all the progress bars on screen
105 eraseProgressBar(nbColTerminal);
106 //Check if we can print first finshed lines definitely
108 //Update the rest of the progress bars to print
109 printProgressBar(nbColTerminal);
110 //We save the previous number of progress bars, in case we print some and add other later
112}
113
116 size_t nbFail(0lu);
117 for(VecProgressElement::const_iterator it(p_vecProgressElement.begin()); it != p_vecProgressElement.end(); ++it){
118 nbFail += it->isEndError;
119 }
120 size_t nbSuccess(p_vecProgressElement.size() - nbFail);
121 std::cout << "PMultiThreadProgress : " << p_vecProgressElement.size() << " computations, " << nbSuccess << " success, " << nbFail << " fail" << std::endl;
122}
123
125
132
134
139 p_nbExpectedProgressBar = nbExpectedProgressBar;
140 p_vecProgressElement.reserve(nbExpectedProgressBar);
141}
142
144
147 std::lock_guard<std::mutex> guard(p_currentMutex);
148 bool isModif(false);
149 size_t i(p_alreadyPrintedLine);
150 while(!isModif && i < p_vecProgressElement.size()){
152 isModif = el.progress != el.prevProgress || el.isEndError;
153 ++i;
154 }
155 return isModif;
156}
157
159
161void PMultiThreadProgress::eraseProgressBar(size_t nbColTerminal){
162 if(p_previousNbProgressBar == 0lu){return;}
163 //Advances method but can't write anyting
164 std::cerr << "\33[2K\r"; //Remove a line where the cursor is
165 for(size_t i(p_alreadyPrintedLine + 1u); i < p_previousNbProgressBar; ++i){
166 std::cerr << "\033[A"; //Go to one line up
167 std::cerr << "\33[2K\r"; //Remove a line where the cursor is
168 }
169}
170
172
174void PMultiThreadProgress::printProgressBar(size_t nbColTerminal){
175 for(size_t i(p_alreadyPrintedLine); i < p_vecProgressElement.size(); ++i){
177 std::cerr << el.name << " : ";
178 if(el.progress >= el.progressMax || el.isEndError){ //This is a finished progress bar but not finaly drawed
179 if(el.isEndError){
180 std::cerr << "\033[31mError\033[0m";
181 for(size_t j(el.name.size() + 8lu); j < nbColTerminal; ++j){
182 std::cerr << " ";
183 }
184 }else{
185 std::cerr << "\033[32mDone\033[0m";
186 for(size_t j(el.name.size() + 7lu); j < nbColTerminal; ++j){
187 std::cerr << " ";
188 }
189 }
190 }else{
191 int avencement = (100*el.progress)/el.progressMax;
192 std::stringstream strAvencement;
193 strAvencement << avencement;
194 std::cerr << avencement << "%";
195 for(size_t j(el.name.size() + 4lu + strAvencement.str().size()); j < nbColTerminal; ++j){
196 std::cerr << " ";
197 }
198 el.prevProgress = el.progress; //Update previous progress
199 }
200 }
201}
202
205 std::lock_guard<std::mutex> guard(p_currentMutex);
206 size_t i(p_alreadyPrintedLine);
207 while(i < p_vecProgressElement.size()){
209 if(el.progress >= el.progressMax || el.isEndError){ //This is a finished progress bar
210 std::cout << el.name << " : ";
211 if(el.isEndError){
212 std::cout << "\033[31mError\033[0m" << std::endl;
213 }else{
214 std::cout << "\033[32mDone\033[0m" << std::endl;
215 }
217 }else{
218 break;
219 }
220 ++i;
221 }
222}
223
225
228 struct winsize w;
229 ioctl(0, TIOCGWINSZ, &w);
230 return w.ws_col;
231}
232
233
void phoenix_print_parallel_progress(PMultiThreadProgress &progress, int refreshSecond)
Print the parallel progression of the computing.
Deal with Progress bar in mutlithread mode.
std::mutex p_currentMutex
Mutex of the class to avoid conflict manipulation between threads.
PMultiThreadProgress & operator=(const PMultiThreadProgress &other)
Definition of equal operator of PMultiThreadProgress.
void printSummary() const
Print a summary of all the progress bars.
size_t p_nbExpectedProgressBar
Number of expected progress bars.
VecProgressElement p_vecProgressElement
Vector of pair (progress, between 0 and 100) and name of progress.
size_t addProgressBar(const PString &name, int progressMax=1)
Add a progress line.
bool isFinished() const
Say if the PMultiThreadProgress is finished.
void print()
Print the multithread progress bar.
PMultiThreadProgress(size_t nbExpectedProgressBar=1lu)
Default constructor of PMultiThreadProgress.
void setNbExpectedProgressBar(size_t nbExpectedProgressBar)
Set the number of expected progress bars in the PMultiThreadProgress.
virtual ~PMultiThreadProgress()
Destructor of PMultiThreadProgress.
bool isModified()
Check if the PMultiThreadProgress has been modified.
void setError(size_t index)
Mark the progress bar at index finished with an error.
void incrementProgress(size_t index)
Increment the progress of the progress bar at index.
void printProgressBar(size_t nbColTerminal)
Print all progress bars.
size_t p_alreadyPrintedLine
Nunmber of already printed line.
void initialisationPMultiThreadProgress(size_t nbExpectedProgressBar)
Initialisation function of the class PMultiThreadProgress.
void eraseProgressBar(size_t nbColTerminal)
Erase all progress bars.
void copyPMultiThreadProgress(const PMultiThreadProgress &other)
Copy function of PMultiThreadProgress.
void printAllFinshedProgressBar()
Print all finished progress bars.
size_t getNbColTerminal() const
Get the number of columns in the current terminal.
size_t p_previousNbProgressBar
Previous number of progress bars.
Single progress information for multithreaded progress bar.
int prevProgress
Previous progression.
PString name
Name of the progress bar.
int progressMax
Maximum of the progression.
bool isEndError
True if the progress ends with an error.
int progress
Current progression.