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();