gpt4 book ai didi

c++ - boost::mutex::scoped_lock 已被使用,有时会抛出异常

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:43:53 24 4
gpt4 key购买 nike

我在我的多线程代码中使用 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 ...
}

我跟踪了代码,发现 basic_timed_mutex 类中有一个变量 active_count ,每当发生运行时错误时,这个变量都未初始化。运行时错误发生在这里:

bool try_lock()
{
return !win32::interlocked_bit_test_and_set(&active_count,lock_flag_bit);
}

我不知道该怎么办!因为我无权访问此变量并且我不负责初始化它。

更新

我的函数类是这样的:

#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;
}

这是我使用 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);
}

}

有一个类继承了MyThreadPool

class SsThreadPool : public MyThreadPool<Job, JobOutput>

这是使用线程池的地方:

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();
//...
}

最佳答案

它会引发访问冲突,因为您试图锁定已销毁的 mutex。由于互斥量是您的类的成员,这意味着您的代码试图访问已销毁实例的成员函数(“悬挂指针”)。要调试这种情况,请在 ~MyThreadPool 中放置一个断点并查看它何时被调用。

关于c++ - boost::mutex::scoped_lock 已被使用,有时会抛出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15379835/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com