Ale*_*exS 7 c++ multithreading boost-thread threadgroup heap-corruption
我对boost :: threads很新,我阅读了文档,但是我在实践中应用它时遇到了一些麻烦,也许你可以帮忙吗?首先,我花时间编写了一个自包含的代码清单,演示了两种我无法理解的行为......
该程序允许用户发出3个不同的命令,
目的是任务将在新线程上启动一些工作,但在执行工作时返回到命令提示符.用户可以使用info命令找出哪些任务已完成,哪些未完成.
我使用双核Win7机器和Visual Studio 2008 Express.
问题1>
发出命令,任务p1 p2 p3,启动3个任务正在运行.这可以通过发布信息来检查.几秒钟后,工作完成,但由于某种原因,完成的标志并不总是在1或2个任务上设置为true.
问题2>
退出程序然后生成以下消息:
Windows在example.exe中触发了断点.这可能是由于堆的损坏,这表示example.exe或它已加载的任何DLL中的错误.这也可能是由于用户在example.exe具有焦点时按下F12.输出窗口可能包含更多诊断信息.
希望您可以重现此行为并提供帮助.
提前致谢.亚历克斯.
//WARNING: THIS CODE DOES NOT BEHAVE EXACTLY AS INTENDED
#include <iostream>
#include <string>
#include <sstream>
#include <boost/thread.hpp>
using namespace std;
class task {
public:
string mname;
bool completed;
void start()
{
int a = 0;
for (int i=0 ; i<10000; i++)
{
for (int j=0 ; j<100000; j++)
{
a= i*2;
}
}
this->completed = true;
}
task(string name)
{
mname = name;
completed = false;
}
};
class taskManager{
public:
boost::thread_group threads;
void startTask( string name )
{
//add new task to vector list
mtasks.push_back( task(name) );
// execute start() on a new thread
threads.create_thread( boost::bind( &task::start, &mtasks.back()) );
}
int tasksTotal()
{
return mtasks.size();
}
string taskInfo(int i)
{
string compstr("Not Completed");
if ( mtasks[i].completed == true )
{
compstr = "Completed";
}
return mtasks[i].mname + " " + compstr;
}
private:
vector<task> mtasks;
};
int main(int argc, char* argv[])
{
string cmd, temp;
stringstream os;
bool quit = false;
taskManager mm;
cout << "PROMPT>";
while (quit == false)
{
//Wait for a valid command from user
getline(cin,cmd);
// Reset stringstream and assign new cmd string
os.clear();
os << "";
os << cmd;
//parse input string
while (os >> temp)
{
if ( temp.compare("task") == 0 )
{
while (os >> temp) { mm.startTask( temp ); }
}
if ( temp.compare("info") == 0 )
{
// Returns a list of all completed and not completed tasks
for (int i = 0; i<mm.tasksTotal(); i++)
{
cout << mm.taskInfo(i).c_str() << endl;
}
}
if ( temp.compare("quit") == 0 ){ quit = true; }
}
cout << "PROMPT>";
}
mm.threads.join_all();
return 0;
};
Run Code Online (Sandbox Code Playgroud)
您的方法中的代码有问题taskManager::startTask
:
mtasks.push_back( task(name) );
// execute start() on a new thread
threads.create_thread( boost::bind( &task::start, &mtasks.back())
Run Code Online (Sandbox Code Playgroud)
这里的问题是,在推迟新任务时,您的向量可能必须重新分配一些空间,从而使对旧向量元素的引用无效,例如以下调用将taskinfo
引用错误的元素。当您删除旧元素时,您的堆会以某种方式损坏。
一个简单的解决方法是在类的构造函数中为向量保留一些空间taskManager
,但是您可能应该更改任务/任务管理器模型的设计。另一种方法是使用 a std::deque
,因为它不会重新分配内存。
归档时间: |
|
查看次数: |
1051 次 |
最近记录: |