[英]boost::mutex::scoped_lock has been used and It sometimes throws the exception
I am using scoped_lock in my multithread code to exclusively access to some part of code, but sometimes it throws to the exception Access violation writing location ... . 我在我的多线程代码中使用scoped_lock来独占访问代码的某些部分,但是有时它会抛出异常访问冲突写入位置...。
boost::mutex mMutex;
boost::condition mInputQueueNotEmpty;
Job* MyThreadPool<Job, JobOutput>::GetNextJob()
{
boost::mutex::scoped_lock lock(mMutex);
while (mInputQueue.empty())
mInputQueueNotEmpty.wait(lock);
// Do something ...
}
I traced the code and I found out that there is a variable active_count in basic_timed_mutex class and whenever the runtime error happens, this variable is uninitialized. 我跟踪了代码,发现在basic_timed_mutex类中有一个变量active_count,并且每当发生运行时错误时,该变量都将被初始化。 runtime error happens around here: 运行时错误发生在这里:
bool try_lock()
{
return !win32::interlocked_bit_test_and_set(&active_count,lock_flag_bit);
}
I do not know what should I do! 我不知道该怎么办! because I do not have access to this variable and I am not responsible for initializing it. 因为我无权访问此变量,因此不负责初始化它。
UPDATE 更新
the class of my function is this: 我函数的类是这样的:
#pragma once
#include <vector.h>
#include <boost/thread.hpp>
#include "MyThread.h"
#include <queue>
#include <boost/thread/condition.hpp>
template <class Job, class JobOutput>
class MyThreadPool
{
public:
MyThreadPool(int processJobWhenArrived);
virtual ~MyThreadPool(void);
void Initialize(int ThreadsCount);
void AddJob(Job* job);
void StartProcess();
Job* GetNextJob();
virtual void FinishJob(Job* job, JobOutput* jobOutput);
void WaitUntilAllJobsProcessed();
public:
vector<MyThread<Job, JobOutput>*> mThreads;
queue<Job*> mInputQueue;
queue<pair<Job*,JobOutput*>> mOutputQueue;
boost::mutex mMutexAdd;
boost::mutex mMutex;
boost::condition mInputQueueNotEmpty;
boost::mutex mJobOutputMutex;
boost::mutex mJobsMutex;
boost::condition mProcessJobs;
bool mStartProcessJobs;
int mJobsInputCount;
int mJobsOutputCount;
int mPrevJobsOutputCount;
bool mProcessJobWhenArrived;
};
template <class Job, class JobOutput>
void MyThreadPool<Job, JobOutput>::Initialize(int threadsCount)
{
mStartProcessJobs = false;
for (int t = 0; t < threadsCount; t++)
mThreads.push_back(new MyThread<Job, JobOutput>(this));
}
template <class Job, class JobOutput>
void MyThreadPool<Job, JobOutput>::AddJob(Job* job)
{
boost::mutex::scoped_lock lock(mMutexAdd);
mInputQueue.push(job);
mJobsInputCount++;
if (mProcessJobWhenArrived)
mInputQueueNotEmpty.notify_all();
}
template <class Job, class JobOutput>
Job* MyThreadPool<Job, JobOutput>::GetNextJob()
{
boost::mutex::scoped_lock lock(mMutex);
if (mInputQueue.empty() && mStartProcessJobs && mJobsInputCount == mJobsOutputCount)
mProcessJobs.notify_one();
while (mInputQueue.empty())
mInputQueueNotEmpty.wait(lock);
Job* job = mInputQueue.front();
mInputQueue.pop();
return job;
}
and this is the code where I use GetNextJob function: 这是我使用GetNextJob函数的代码:
#pragma once
#include <MyMemory.h>
#include <boost/thread.hpp>
template <class Job, class JobOutput>
class MyThreadPool;
template <class Job, class JobOutput>
class MyThread
{
public:
static void StaticRun(MyThread* p);
void Run();
public:
boost::thread mThread;
MyThreadPool<Job, JobOutput>* mThreadPool;
};
#include "MyThreadPool.h"
template <class Job, class JobOutput>
MyThread<Job, JobOutput>::MyThread(MyThreadPool<Job, JobOutput>* threadPool)
{
mThread = boost::thread(StaticRun, this);
mThreadPool = threadPool;
}
template <class Job, class JobOutput>
void MyThread<Job, JobOutput>::StaticRun(MyThread* p)
{
p->Run();
}
template <class Job, class JobOutput>
void MyThread<Job, JobOutput>::Run()
{
JobOutput *jobOutput;
while (true)
{
Job* job = mThreadPool->GetNextJob();
jobOutput = Process (job);
mThreadPool->FinishJob(job, jobOutput);
}
}
there is a class that inhrerits MyThreadPool 有一个类会激怒MyThreadPool
class SsThreadPool : public MyThreadPool<Job, JobOutput>
and this is where threadPool has been used: 这是使用threadPool的地方:
class BPS
{
//...
SsThreadPool mJobsThreadPool;
//...
}
void BPS::Initialize()
{
mJobsThreadPool.Initialize(mConcurrentThreadsCount);
}
void BPS::f()
{
//...
for (int i = 0; i < jobsCount; i++)
{
//...
mJobsThreadPool.AddJob(job);
//...
}
mJobsThreadPool.StartProcess();
mJobsThreadPool.WaitUntilAllJobsProcessed();
//...
}
It raises access violation, because you attempt to lock a destroyed mutex
. 因为您尝试锁定损坏的mutex
锁,所以会引起访问冲突。 Since the mutex is a member of your class, it means your code attempts to access a member-function of a destroyed instance ("dangling pointer"). 由于互斥锁是您的类的成员,所以这意味着您的代码尝试访问已破坏实例的成员函数(“悬挂指针”)。 To debug this case, put a breakpoint in ~MyThreadPool
and see when it gets called. 要调试这种情况,请在~MyThreadPool
放置一个断点,看看何时调用它。
Maybe the object,that is holding the mutex, gets destroyed and then someone is trying to access the mutex. 可能是持有互斥锁的对象被破坏,然后有人试图访问该互斥锁。 possible in your code ? 您的代码中可能吗?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.