c++ Boost 多线程 CPU 和内存使用率又慢又高 - 需要帮助
我正在使用 boost 库创建带有互斥锁的多线程。我基于谷歌上的一些例子。多头工作正常,但 CPU 为 100%,任务管理器的内存使用量为 300K+。我的两个多线程函数执行非常高的数据转换和分析。我不确定我是否错过了什么。这是我的多线程的一部分:
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();
我需要在这些函数中做一些事情吗?提前致谢。我使用 Dell Optilex 745 Pentium D 进行了测试。我不确定它是否支持多线程。我已经打印了hard_concurrent,它显示在1上。
其中一个函数 - 摘要
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;
}
}
}
}
第一个线程上的另一个简短函数:
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);
}
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);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这对我来说看起来不正确:
这只能保护线程的创建不与其他任何线程同时运行,它对该线程执行的操作没有影响。您需要从线程函数内锁定互斥体以获得任何保护。
此外,正如评论中指出的,
wait
是可疑的,不需要。最后,您应该(在我看来)永远不要直接使用 mutex.lock/mutex.unlock,因为它很容易出错,尤其在存在异常的情况下。使用 Boost 提供的 RAII 工具,例如
scoped_lock
。要获得更多信息,您必须向我们展示这些线程函数实际上在做什么。
This doesn't look right to me:
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.