boost :: threads示例和堆损坏消息

我很兴奋boost :: threads,我阅读了文档,但在实践中遇到了一些麻烦,也许你可以帮忙? 首先,我花时间编写了一个自包含的代码清单,演示了我还不能理解的两种行为类型......

该程序允许用户发出3个不同的命令,

  • 任务名称]
  • 信息
  • 放弃
  • 目的是任务将在新线程上启动一些工作,但在工作执行时返回命令提示符。 用户可以通过info命令找出哪些任务已完成,哪些尚未完成。

    我使用双核Win7机器和Visual Studio 2008 Express。

    问题1>

    发出命令,任务p1 p2 p3,开始运行3个任务。 这可以通过发布信息来检查。 几秒钟后,工作完成,但由于某种原因,完成的标志并不总是在1或2个任务上设置为真。

    问题2>

    退出程序然后产生以下消息:

    Windows已经在example.exe中触发了一个断点。 这可能是由于堆损坏引起的,这表明example.exe或其中已加载的任何DLL都存在缺陷。 这也可能是由于用户按下F12而example.exe有焦点。 输出窗口可能有更多的诊断信息。

    希望你能重现这种行为和帮助。

    提前致谢。 亚历克斯。

        //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;  
    };
    

    您的代码在taskManager::startTask方法中存在问题:

    mtasks.push_back( task(name) );
    // execute start() on a new thread
    threads.create_thread( boost::bind( &task::start, &mtasks.back())
    

    这里的问题是,在推回新任务时,您的向量可能不得不重新分配一些空间,并且使对旧向量元素的引用无效,因此以下对taskinfo调用将引用错误的元素。 当你删除旧的元素时,堆会以某种方式被损坏。

    一个简单的解决方法是在taskManager类的构造函数中为矢量保留一些空间,但是您应该改为改变task / taskmanager模型的设计。 另一种方法是使用std::deque ,因为那个不会重新分配内存。

    链接地址: http://www.djcxy.com/p/59125.html

    上一篇: boost::threads example and heap corruption message

    下一篇: ManyToOne with where clause