C++ 当我在另一个类中添加另一个条件变量(类似于阻塞事件队列)时出现了问题。@inkooboo我已在答案底部添加了实时演示-您可以尝试使用它(可能添加其他部分)以重现崩溃。我已将事件队列代码添加到您的示例中。不幸的是,我无法复制崩溃。但您可以研究代码,可能会有一

C++ 当我在另一个类中添加另一个条件变量(类似于阻塞事件队列)时出现了问题。@inkooboo我已在答案底部添加了实时演示-您可以尝试使用它(可能添加其他部分)以重现崩溃。我已将事件队列代码添加到您的示例中。不幸的是,我无法复制崩溃。但您可以研究代码,可能会有一,c++,multithreading,boost,actor,C++,Multithreading,Boost,Actor,当我在另一个类中添加另一个条件变量(类似于阻塞事件队列)时出现了问题。@inkooboo我已在答案底部添加了实时演示-您可以尝试使用它(可能添加其他部分)以重现崩溃。我已将事件队列代码添加到您的示例中。不幸的是,我无法复制崩溃。但您可以研究代码,可能会有一些想法。谢谢,谢谢你的帮助。还是不能解决我的问题。将您的其他答案向上投票。@inkooboo此外,您还可以通过安全检查(无双重解锁或锁定)生成DebugMutex。顺便问一下,您是否仍然收到与原始问题相同的错误消息?谢谢。经过一天的调试,我可以


当我在另一个类中添加另一个条件变量(类似于阻塞事件队列)时出现了问题。@inkooboo我已在答案底部添加了实时演示-您可以尝试使用它(可能添加其他部分)以重现崩溃。我已将事件队列代码添加到您的示例中。不幸的是,我无法复制崩溃。但您可以研究代码,可能会有一些想法。谢谢,谢谢你的帮助。还是不能解决我的问题。将您的其他答案向上投票。@inkooboo此外,您还可以通过安全检查(无双重解锁或锁定)生成
DebugMutex
。顺便问一下,您是否仍然收到与原始问题相同的错误消息?谢谢。经过一天的调试,我可以说它看起来像内存腐蚀。我将break设置为boost::thread::interrupt(),并确保没有人调用它。同时,它是一个可以设置“中断请求”标志的单一位置。目前,我正在尝试查找内存损坏发生的位置。您正在使用visual studio吗?据我所知,它有一些宏定义,可以检查堆的一致性。不,这是linux解决方案。我使用valgrind并从外部库中检测到一些“无效写入”。幸运的是,我有它的源代码,所以可以解决这个问题。“在我的情况下,当他们都试图在创建时更改此存储时出现了问题”-如果看到一些代码显示这一点,那将是很好的。可能,这是Boost中的错误-因此我们应该报告它。“我将代码中的Boost::thread_specific_ptr替换为uu thread specified变量。”-因此,另一个TLS插槽将损坏?=)
class Actor {

  public:
    typedef boost::function<int()> Job;

  private:
    std::queue<Job>             d_jobQueue;
    boost::mutex                d_jobQueueMutex;
    boost::condition_variable   d_hasJob;
    boost::atomic<bool>         d_keepWorkerRunning;
    boost::thread               d_worker;

    void workerThread();

  public:
    Actor();
    virtual ~Actor();

    void execJobAsync(const Job& job);

    int execJobSync(const Job& job);
};
namespace {

int executeJobSync(std::string          *error,
                   boost::promise<int> *promise,
                   const Actor::Job     *job)
{
    int rc = (*job)();

    promise->set_value(rc);
    return 0;
}

}

void Actor::workerThread()
{
    while (d_keepWorkerRunning) try {
        Job job;
        {
            boost::unique_lock<boost::mutex> g(d_jobQueueMutex);

            while (d_jobQueue.empty()) {
                d_hasJob.wait(g);
            }

            job = d_jobQueue.front();
            d_jobQueue.pop();
        }

        job();
    }
    catch (...) {
        // Log error
    }
}

void Actor::execJobAsync(const Job& job)
{
    boost::mutex::scoped_lock g(d_jobQueueMutex);
    d_jobQueue.push(job);
    d_hasJob.notify_one();
}

int Actor::execJobSync(const Job& job)
{
    std::string error;
    boost::promise<int> promise;
    boost::unique_future<int> future = promise.get_future();

    {
        boost::mutex::scoped_lock g(d_jobQueueMutex);
        d_jobQueue.push(boost::bind(executeJobSync, &error, &promise, &job));
        d_hasJob.notify_one();
    }

    int rc = future.get();

    if (rc) {
        ErrorUtil::setLastError(rc, error.c_str());
    }

    return rc;
}

Actor::Actor()
: d_keepWorkerRunning(true)
, d_worker(&Actor::workerThread, this)
{
}

Actor::~Actor()
{
    d_keepWorkerRunning = false;
    {
        boost::mutex::scoped_lock g(d_jobQueueMutex);
        d_hasJob.notify_one();
    }
    d_worker.join();
}
g.release(); // <------------ PATCH
d_jobQueueMutex.unlock();
while (d_jobQueue.empty()) {
    d_hasJob.wait(g);
}
d_keepWorkerRunning = false;
d_hasJob.notify_one();
~Actor()
{
    execJobSync([this]()->int
    {
        d_keepWorkerRunning = false;
        return 0;
    });
    d_worker.join();
}
int Actor::execJobSync(const Job& job)
{
    if (boost::this_thread::interruption_requested())
        std::cout << "Interruption requested!" << std::endl;
    std::string error;
    boost::promise<int> promise;
    boost::unique_future<int> future = promise.get_future();