c++ Boost 多线程 CPU 和内存使用率又慢又高 - 需要帮助

发布于 2024-10-30 06:29:36 字数 4002 浏览 0 评论 0原文

我正在使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

烂人 2024-11-06 06:29:36

这对我来说看起来不正确:

mutex.lock();
boost::thread t6(...);
mutex.unlock();

这只能保护线程的创建不与其他任何线程同时运行,它对该线程执行的操作没有影响。您需要从线程函数内锁定互斥体以获得任何保护。

此外,正如评论中指出的, wait 是可疑的,不需要。

最后,您应该(在我看来)永远不要直接使用 mutex.lock/mutex.unlock,因为它很容易出错,尤其在存在异常的情况下。使用 Boost 提供的 RAII 工具,例如 scoped_lock

要获得更多信息,您必须向我们展示这些线程函​​数实际上在做什么。

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 waits 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文