Reputation: 177
I am using boost library to create multithread with mutex. I based on some example on google. The multitrheads are working fine, but CPU are 100%, memory usage from task manager are 300K+. My two multithread functions are performed very high data conversion and analysis. I am not sure if I missed somethings. Here are the part of my multithread:
wait(1);
mutex.lock();
boost::thread t1(&YExcel::BasicExcelCell::TTiTraceParserConv,c,TTiAsciiTraceOutputDL.GetBuffer(0));
mutex.unlock();
wait(2);
mutex.lock();
boost::thread t2(&YExcel::BasicExcelCell::TTiTraceParserConv,c,TTiAsciiTraceOutputUL.GetBuffer(0));
mutex.unlock();
t1.join();
t2.join();
wait(2);
wait(1);
mutex.lock();
boost::thread t5(&YExcel::BasicExcelCell::UeAndCellParamParseUL,c,TTiAsciiTraceOutputUL.GetBuffer(0), NumOfLinesUL,GHOSTFILTER);
mutex.unlock();
wait(2);
mutex.lock();
boost::thread t6(&YExcel::BasicExcelCell::UeAndCellParamParseDL,c,TTiAsciiTraceOutputDL.GetBuffer(0), NumOfLinesDL);
mutex.unlock();
t5.join();
t6.join();
Do I need to do somethings inside those functions? Thanks in advance. I was tested with Dell Optilex 745 Pentium D. I am not sure it supports Multi-thread. I had printed hard_concurrent, it showed on 1.
One of the function - summary
int BasicExcelCell::UeAndCellParamParseDL(char *inname, int NumOfRecords)
{
typedef boost::tokenizer <boost::escaped_list_separator<char> > my_tokenizer;
....
....
CString TTiAsciiTraceOutput(inname);
TTiAsciiTraceOutput.Replace(".dat","_raw.txt");
ifstream infile(TTiAsciiTraceOutput.GetBuffer(0));
if (!infile)
{
cout << "Couldn't open file " << TTiAsciiTraceOutput.GetBuffer(0) << " for reading." << endl;
return EXIT_FAILURE;
}
cout << "\nOpened file " << TTiAsciiTraceOutput.GetBuffer(0) << " for reading." << endl << endl;
int lineCount=0;
getline(infile, line);
if (NumOfRecords < 0)
{
cout<<"Number Of Lines to be parsed is not specified!"<<endl;
return 0;
}
while (getline(infile, line) && lineCount <= NumOfRecords)
{
lineCount++;
int FoundCrntiEmpty=0;
my_tokenizer tok(line);
int i = 0;
for (my_tokenizer::iterator it(tok.begin()), end(tok.end()); it != end; ++it)
{
mystr.push_back(*it);
}
int tokcount=0;
int SingleTx=0;
int TxDiv=0;
int tokCountFlag=0;
double MetricCalTemp=0.0;
for (vector < string >::iterator mit(mystr.begin()); mit != mystr.end(); mit++)
{
for (vector < string >::iterator _mit(mystr.begin()); _mit != mystr.end(); _mit++)
{
tokCountFlag++;
if (tokCountFlag==60)
break;//not need to goto the whole iterator
switch (tokCountFlag)
{
case 29:
<<*_mit<<endl;
if (*_mit=="0")
FoundCrntiEmpty=1;
break;
case 58:
//cout<<"Single or Tx " <<*_mit<<endl;
if (*_mit == "0")
SingleTx=1;
else if (*_mit == "1")
TxDiv=1;
break;
}
}
}
}
Another short function on first thread:
void BasicExcelCell::TTiTraceParserConv(char *p_resFile)
{
char ttiTraceParser[512];
char ttiTraceConfig[512];
char cwd[512];
size_t size;
char OrigDLFile[512];
GetModuleFileName(NULL, cwd, 512);
char * CollectTTiTraceAdvance_exe;
CollectTTiTraceAdvance_exe = strstr (cwd,"CollectTTiTraceAdvance.exe");
strncpy (CollectTTiTraceAdvance_exe,"",26);
CString TTiAsciiTraceOutput(p_resFile);
CString ParserExe, TraceConfig;
ParserExe.Format(_T("%s\\BinaryFileParser\\tti_trace_parser_wmp.exe "),cwd);
sprintf(OrigDLFile,"%s",TTiAsciiTraceOutput.GetBuffer(0));
TTiAsciiTraceOutput.Replace(".dat","_raw.txt");
TraceConfig.Format(_T(" %s\\%s %s\\%s"),cwd,OrigDLFile,cwd,TTiAsciiTraceOutput);
cout<<"\n\n****Prepare to generate RawFile!!!"<<endl;
ShellAndWait(ParserExe.GetBuffer(0),TraceConfig.GetBuffer(0),"WAIT",240,1);//4 minutes
ParserExe.ReleaseBuffer(0);
TraceConfig.ReleaseBuffer(0);
}
Upvotes: 1
Views: 1252
Reputation: 23128
This doesn't look right to me:
mutex.lock();
boost::thread t6(...);
mutex.unlock();
This only protects the creation of the thread from running concurrently with anything else, it has no effect on the operations carried out by that thread. You'll need to lock the mutex from within the thread function to gain any protection.
In addition, as pointed out in the comments, the wait
s are suspicious and should not be needed.
Finally, you should (in my opinion) never use mutex.lock/mutex.unlock directly because it's error-prone, especially in the presence of exceptions. Use the RAII tools such as scoped_lock
which are provided by Boost.
To get any more information, you'll have to show us what those thread functions are actually doing.
Upvotes: 1