簡體   English   中英

boost :: mutex :: scoped_lock已被使用,有時會拋出異常

[英]boost::mutex::scoped_lock has been used and It sometimes throws the exception

我在我的多線程代碼中使用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>

這是使用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();
    //...
}

因為您嘗試鎖定損壞的mutex鎖,所以會引起訪問沖突。 由於互斥鎖是您的類的成員,所以這意味着您的代碼嘗試訪問已破壞實例的成員函數(“懸掛指針”)。 要調試這種情況,請在~MyThreadPool放置一個斷點,看看何時調用它。

可能是持有互斥鎖的對象被破壞,然后有人試圖訪問該互斥鎖。 您的代碼中可能嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM