最近在做毕设的时候遇到了一个Vector的Iterator意外失效的问题,分析下来,是因为使用了多线程,在对一个成员变量进行读写操作的时候没有加锁导致的,下面有一个编写的简单的例子来说明这个问题。 本例子中使用了ACE_Task(主动对象:ACE中的一种模式,将线程封装在对象中) 问题代码: #pragma once #pragma comment(lib,"ACEd.lib") #include "ace/Task.h" #include "ace/Synch.h" #include "ace/OS.h" #include <iostream> #include <string> #include <vector> class CMyThread:public ACE_Task<ACE_MT_SYNCH> { public: void Init(); int svc(void);//线程函数 bool ChangeVector(); private: bool ReadVector(); private: int m_Count; std::vector<std::string> m_StringVec; }; void CMyThread::Init() { m_StringVec.clear(); std::string str = "string"; m_StringVec.push_back(str); m_Count = 0; } int CMyThread::svc(void) { while(1) { ReadVector(); ACE_OS::sleep(3); } return 1; } bool CMyThread::ReadVector() { std::vector<std::string>::const_iterator m_StrIt; for (m_StrIt = m_StringVec.begin();m_StrIt !=.end();m_StrIt++) { std::cout<<(*m_StrIt).c_str()<<" "; } std::cout<<std::endl<<"================="<<std::endl; return true; } bool CMyThread::ChangeVector() { m_Count++; char cStr[20]; memset(cStr,'\0',20); ::sprintf(cStr,"string%d",m_Count); m_StringVec.push_back(cStr); return true; } int main(int arg,char * argc[]) { CMyThread thread; thread.Init(); thread.activate(); while(1) { thread.ChangeVector(); ACE_OS::sleep(2); } getchar(); return 0; } 程序的运行的结果是:程序出现错误,输出不正确 控制台输出如下: 这就是Vector的迭代器失效的问题,主要是因为在多线程中,没有对临界区(m_StringVec)没有进行互斥控制。 解决方法:在相应的临界区上加上互斥锁 Code: #pragma once #pragma comment(lib,"ACEd.lib") #include "ace/Task.h" #include "ace/Synch.h" #include "ace/OS.h" #include "ace/Mutex.h" #include "ace/Guard_T.h" #include <iostream> #include <string> #include <vector> class CMyThread:public ACE_Task<ACE_MT_SYNCH> { public: void Init(); int svc(void);//线程函数 bool ChangeVector(); private: bool ReadVector(); private: int m_Count; ACE_MT_SYNCH::MUTEX m_Mutex; //互斥锁 std::vector<std::string> m_StringVec; }; void CMyThread::Init() { m_StringVec.clear(); std::string str = "string"; m_StringVec.push_back(str); m_Count = 0; } int CMyThread::svc(void) { while(1) { ReadVector(); ACE_OS::sleep(3); } return 1; } bool CMyThread::ReadVector() { ACE_Guard<ACE_MT_SYNCH::MUTEX> monitor(m_Mutex); std::vector<std::string>::const_iterator m_StrIt; for (m_StrIt = m_StringVec.begin();m_StrIt !=.end();m_StrIt++) { std::cout<<(*m_StrIt).c_str()<<" "; } std::cout<<std::endl<<"================="<<std::endl; return true; } bool CMyThread::ChangeVector() { m_Count++; char cStr[20]; memset(cStr,'\0',20); ::sprintf(cStr,"string%d",m_Count); ACE_Guard<ACE_MT_SYNCH::MUTEX> monitor(m_Mutex); m_StringVec.push_back(cStr); return true; } int main(int arg,char * argc[]) { CMyThread thread; thread.Init(); thread.activate(); while(1) { thread.ChangeVector(); ACE_OS::sleep(2); } getchar(); return 0; } 输出就正常了! 另:ACE_Task中的Message_Queue就是使用的加锁+条件变量的机制进行同步和互斥的