C++ 信号量wxwidgets异常

C++ 信号量wxwidgets异常,c++,visual-studio-2013,wxwidgets,C++,Visual Studio 2013,Wxwidgets,我使用WxWidget中的一个示例来了解如何进行线程间和进程间通信。我不知道为什么这个示例会起作用,但我的代码非常类似,在“m_QueueCount.Wait();//等待信号量(=队列计数变为正值)”行没有显示 当我运行代码时,会显示一个exeption: TeamTranslate.exe中0x00B2DB61处的首次机会异常:0xC0000005: 访问冲突读取位置0x00000078 如果存在此异常的处理程序,则程序可能会安全运行 继续 断点位于xstring文件的第1749行。代码如下

我使用WxWidget中的一个示例来了解如何进行线程间和进程间通信。我不知道为什么这个示例会起作用,但我的代码非常类似,在“m_QueueCount.Wait();//等待信号量(=队列计数变为正值)”行没有显示

当我运行代码时,会显示一个exeption:

TeamTranslate.exe中0x00B2DB61处的首次机会异常:0xC0000005: 访问冲突读取位置0x00000078

如果存在此异常的处理程序,则程序可能会安全运行 继续

断点位于xstring文件的第1749行。代码如下:

size_type length() const _NOEXCEPT
        {   // return length of sequence
        return (this->_Mysize);
        }
我希望有人能告诉我为什么这样不行

先谢谢你

标题:

class QueueMSG
{
public:
    QueueMSG(wxEvtHandler* pParent) : m_pParent(pParent) {}
    void AddJob(MessagePTR job); // push a job with given priority class onto the FIFO
    MessagePTR Pop();
    void Report(const Message::tCOMMANDS& cmd, MessagePTR arg); // report back to parent
    size_t Stacksize(); // helper function to return no of pending jobs

private:
    wxEvtHandler* m_pParent;
    std::vector<MessagePTR> m_Jobs; // multimap to reflect prioritization: values with lower keys come first, newer values with same key are appended
    wxMutex m_MutexQueue; // protects queue access
    wxSemaphore m_QueueCount; // semaphore count reflects number of queued jobs
};

class WorkerThread : public wxThread
{
public:
    WorkerThread(QueueMSG* pQueue) : m_pQueue(pQueue) { wxThread::Create(); }

private:
    QueueMSG* m_pQueue;
    BingTranslate bng;
    virtual wxThread::ExitCode Entry();
    virtual void OnJob();
}; // class WorkerThread : public wxThread
class-QueueMSG
{
公众:
QueueMSG(wxEvtHandler*pParent):m_pParent(pParent){}
void AddJob(MessagePTR job);//将具有给定优先级的作业推送到FIFO上
MessagePTR-Pop();
无效报告(const Message::tCOMMANDS&cmd,MessagePTR arg);//报告回父级
size_t Stacksize();//用于返回挂起作业数的帮助函数
私人:
wxEvtHandler*m_pParent;
std::vector m_Jobs;//反映优先级的多重映射:具有较低键的值优先,具有相同键的较新值被追加
wxMutex m_MutexQueue;//保护队列访问
wxSemaphore m_QueueCount;//信号量计数反映排队作业的数量
};
类WorkerThread:public wxThread
{
公众:
WorkerThread(QueueMSG*pQueue):m_pQueue(pQueue){wxThread::Create();}
私人:
QueueMSG*m_pQueue;
宾格;
虚拟wxThread::ExitCode Entry();
虚拟void OnJob();
}; // 类WorkerThread:public wxThread
cpp:

void QueueMSG::AddJob(MessagePTR job)//将具有给定优先级的作业推送到FIFO上
{
wxMutexLocker lock(m_MutexQueue);//锁定队列
m_Jobs.push_back(job);//将按优先级排序的条目插入多重映射
m_QueueCount.Post();//新作业已到达:增量信号量计数器
}//void AddJob(const tJOB&job,const tPRIORITY&priority=normal)
MessagePTR QueueMSG::Pop()
{
std::vector::迭代器元素;
m_QueueCount.Wait();//等待信号量(=队列计数变为正)
m_MutexQueue.Lock();//锁定队列
element=m_Jobs.begin();//从队列中获取第一个条目(优先级较高的类优先)
m_Jobs.erase(m_Jobs.begin());//删除它
m_MutexQueue.Unlock();//解锁队列
return*element;//返回作业条目
}//tJOB Pop()
void QueueMSG::Report(const Message::tCOMMANDS&cmd,MessagePTR arg)//报告回父级
{
wxThreadEvent evt(wxEVT_THREAD,wxID_ANY);//cmd);//创建命令事件对象
evt.SetPayload(arg);//将字符串与其关联
wxQueueEvent(m_pParent,evt.Clone());
//m_pParent->AddPendingEvent(evt);//并将其添加到父级的事件队列中
}//无效报告(const tJOB::tCOMMANDS&cmd,const wxString&arg=wxEmptyString)
size\u t QueueMSG::Stacksize()
{
wxMutexLocker lock(m_MutexQueue);//锁定队列,直到读取大小
返回m_Jobs.size();
}
void WorkerThread::OnJob()
{
MessagePTR job=m_pQueue->Pop();//从队列中弹出作业。如果队列为空,这将阻止工作线程
b.翻译这项工作;
开关(作业->m_命令)
{
案例消息::eID_THREAD_EXIT://线程应退出
//睡觉(1000);//等一会儿
抛出消息::eID_THREAD_EXIT;//确认退出命令
案例消息::eID_THREAD_JOB://处理标准作业
//睡眠(2000年);
m_pQueue->Report(Message::eID_THREAD_JOB,JOB);//报告成功完成
打破
案例消息::eID_THREAD_JOBERR://处理以错误终止的作业
m_PQUE->报告(消息::eID_线程_作业,作业);
//睡眠(1000);
抛出消息::eID_THREAD_EXIT;//报告工作线程的退出
打破
案例消息::eID_THREAD_NULL://伪命令
默认值:break;//默认值
}//开关(job.m\u cmd)
}//虚拟void OnJob()
wxThread::ExitCode WorkerThread::Entry()
{
消息::tCOMMANDS iErr;
m_pQueue->Report(Message::eID_THREAD_STARTED,NULL);//告诉主线程工作线程已成功启动
试一试{
while(true)
在职();
}//这是主循环:处理作业,直到作业处理程序抛出
捕获(消息::tCOMMANDS&i){
m_PQUE->报告(iErr=i,空);
}//从错误条件捕获返回值
return(wxThread::ExitCode)iErr;//并返回退出代码
}//虚拟wxThread::ExitCode Entry()
消息类:

#pragma once


#include <cstring>
#include <stdio.h>
#include <wx/string.h>
#include <vector>

#include <memory>

enum MSGDirection{
    in,
    out
};

class Message {

public:
    enum tCOMMANDS // list of commands that are currently implemented
    {
        eID_THREAD_EXIT = wxID_EXIT, // thread should exit or wants to exit
        eID_THREAD_NULL = wxID_HIGHEST + 1, // dummy command
        eID_THREAD_STARTED, // worker thread has started OK
        eID_THREAD_JOB, // process normal job
        eID_THREAD_JOBERR // process errorneous job after which thread likes to exit
    }; // enum tCOMMANDS
    Message(MSGDirection dir, wxString from, wxString message, wxString language_org, wxString language_dest) : m_message(message), m_dir(dir), m_from(from), m_language_orig(language_org), m_language_dest(language_dest), m_cmd(eID_THREAD_EXIT){

        time_t          rawtime;
        struct tm*      timeinfo;
        char            timestamp[100];

        time(&rawtime);
        timeinfo = localtime(&rawtime);
        strftime(timestamp, 100, "%c", timeinfo);
        m_timestamp = timestamp;
    }
    Message() : m_cmd(eID_THREAD_NULL) {}

    ~Message(){ }

    void setIO(MSGDirection dir);
    MSGDirection getIO(){ return m_dir; };
    void setFrom(char* dir);
    wxString getFrom(){ return m_from; };

    void setMSG(wxString dir){
        m_message = dir;
    };
    wxString getMSG(){ return m_message; }
    wxString getTranslated(){ return m_translated; }
    wxString getTimeStamp(){ return m_timestamp; }
    wxString getLanguageOrig(){ return m_language_orig; }

    wxString getLanguageDest(){ return m_language_dest; }
    void  setSrtTranslate(wxString str){ m_translated = str; }
    tCOMMANDS m_cmd;
private:
    MSGDirection m_dir;
    wxString m_language_orig;
    wxString m_from;
    wxString m_message;
    wxString m_timestamp;
    wxString m_language_dest;
    wxString m_translated;

};


typedef std::shared_ptr<Message> MessagePTR;
typedef std::shared_ptr<std::vector<MessagePTR>> MessageQueuePTR;
#pragma一次
#包括
#包括
#包括
#包括
#包括
枚举MSGDirection{
在里面
出来
};
类消息{
公众:
枚举tCOMMANDS//当前执行的命令列表
{
eID_THREAD_EXIT=wxID_EXIT,//线程应该退出或想要退出
eID_THREAD_NULL=wxID_HIGHEST+1,//伪命令
eID\u线程\u已启动,//工作线程已启动正常
eID_线程_作业,//处理正常作业
eID_THREAD_JOBERR//process errorneous job线程希望退出的作业
};//枚举tCOMMANDS
消息(MSGDirection dir,wxString from,wxString Message,wxString language_org,wxString language_dest):消息(Message),消息(dir),消息(from),语言(from),语言(language_org),语言(language_dest),命令(eID_THREAD_EXIT){
时间与时间;
结构tm*时间信息;
字符时间戳[100];
时间(&rawtime);
timeinfo=localtime(&rawtime);
strftime(时间戳,100,“%c”,timeinfo);
m_timestamp=时间戳;
}
Message():m_cmd(eID_THREAD_NULL){}
~Message(){}
无效设置(MSGDirection dir);
MSGDirection getIO(){return m_dir;};
void setFrom(char*dir);
wxString getFrom(){return m_from;};
void setMSG(wxString dir){
m_message=dir;
};
wxString getMSG(){r
#pragma once


#include <cstring>
#include <stdio.h>
#include <wx/string.h>
#include <vector>

#include <memory>

enum MSGDirection{
    in,
    out
};

class Message {

public:
    enum tCOMMANDS // list of commands that are currently implemented
    {
        eID_THREAD_EXIT = wxID_EXIT, // thread should exit or wants to exit
        eID_THREAD_NULL = wxID_HIGHEST + 1, // dummy command
        eID_THREAD_STARTED, // worker thread has started OK
        eID_THREAD_JOB, // process normal job
        eID_THREAD_JOBERR // process errorneous job after which thread likes to exit
    }; // enum tCOMMANDS
    Message(MSGDirection dir, wxString from, wxString message, wxString language_org, wxString language_dest) : m_message(message), m_dir(dir), m_from(from), m_language_orig(language_org), m_language_dest(language_dest), m_cmd(eID_THREAD_EXIT){

        time_t          rawtime;
        struct tm*      timeinfo;
        char            timestamp[100];

        time(&rawtime);
        timeinfo = localtime(&rawtime);
        strftime(timestamp, 100, "%c", timeinfo);
        m_timestamp = timestamp;
    }
    Message() : m_cmd(eID_THREAD_NULL) {}

    ~Message(){ }

    void setIO(MSGDirection dir);
    MSGDirection getIO(){ return m_dir; };
    void setFrom(char* dir);
    wxString getFrom(){ return m_from; };

    void setMSG(wxString dir){
        m_message = dir;
    };
    wxString getMSG(){ return m_message; }
    wxString getTranslated(){ return m_translated; }
    wxString getTimeStamp(){ return m_timestamp; }
    wxString getLanguageOrig(){ return m_language_orig; }

    wxString getLanguageDest(){ return m_language_dest; }
    void  setSrtTranslate(wxString str){ m_translated = str; }
    tCOMMANDS m_cmd;
private:
    MSGDirection m_dir;
    wxString m_language_orig;
    wxString m_from;
    wxString m_message;
    wxString m_timestamp;
    wxString m_language_dest;
    wxString m_translated;

};


typedef std::shared_ptr<Message> MessagePTR;
typedef std::shared_ptr<std::vector<MessagePTR>> MessageQueuePTR;
MessagePtr msg;
m_QueueCount.Wait();
{
    wxMutexLocker lock( m_MutexQueue );
    auto element = m_Jobs.begin();
    msg = *element;
    m_Jobs.erase(element);
}
return msg;
element=(m_Jobs.begin())->second; // that '->'