우선 순위가 높은 스레드에서 실행되는 높은 우선 순위 기능을 가진 dll이 있습니다. 이 dll은 진행 상황을보고해야합니다. 기본적으로 콜백 시스템이 사용됩니다. 문제는 dll이 콜백이 완료되는 데 걸리는 시간을 제어 할 수 없다는 것입니다. 즉, 우선 순위가 높은 기능은 콜백 구현에 따라 달라지며 이는 받아 들일 수 없습니다.스레드 안전 큐에서 잠금 범위를 좁게하십시오.
아이디어는 진행 중 알림을 버퍼링하고 콜백을 호출하는 클래스를 갖는 것입니다.
저는 C++ 11을 처음 접했고 기능을 스레딩하고 가능성을 발견하려고합니다. 구현이 있지만 문제가 있습니다 (적어도 하나는 지금 볼 수 있음). 기다린 후에 스레드가 깨어 나면 뮤텍스가 다시 획득되고 다음 대기 때까지 획득 상태를 유지합니다. 즉, 긴 작업이 계속 진행되는 동안 잠금이 획득됩니다. 진행 상황을 추가하면 여기에서 차단됩니다. 기본적으로 많은 이득을위한 코드. 코드를이 코드로 변경하려고 생각했지만 이것이 올바른 구현인지 여부는 알 수 없습니다.
Progress progress = queue.front();
queue.pop();
lock.unlock();
// Do lengthy operation with progress
lock.lock();
나는 조건 변수를 기다릴 필요가 있다고 생각하지만 잠금 장치에 연결하면 안된다. 어떻게 할 수 있는지 모르겠습니다. 더미 잠금 장치를 전달하고 큐를 보호하기 위해 다른 잠금 장치를 사용합니까? 이 문제는 C++ 11에서 어떻게 처리되어야합니까?
헤더 파일
#include <atomic>
#include <condition_variable>
#include <mutex>
#include <thread>
#include <queue>
#include "Error.h"
#include "TypeDefinitions.h"
struct Progress
{
StateDescription State;
uint8 ProgressPercentage;
};
class ProgressIsolator
{
public:
ProgressIsolator();
virtual ~ProgressIsolator();
void ReportProgress(const Progress& progress);
void Finish();
private:
std::atomic<bool> shutdown;
std::condition_variable itemAvailable;
std::mutex mutex;
std::queue<Progress> queue;
std::thread worker;
void Work();
};
CPP 파일이 향하고있다하지만이 같은 기능을 제공하지 않는 경우 내가 볼
#include "ProgressIsolator.h"
ProgressIsolator::ProgressIsolator() :
shutdown(false),
itemAvailable(),
worker([this]{ Work(); }),
progressCallback(progressCallback),
completedCallback(completedCallback)
{
// TODO: only continue when worker thread is ready and listening?
}
ProgressIsolator::~ProgressIsolator()
{
Finish();
worker.join();
}
void ProgressIsolator::ReportProgress(const Progress& progress)
{
std::unique_lock<std::mutex> lock(mutex);
queue.push(progress);
itemAvailable.notify_one();
}
void ProgressIsolator::Finish()
{
shutdown = true;
itemAvailable.notify_one();
}
void ProgressIsolator::Work()
{
std::unique_lock<std::mutex> lock(mutex);
while (!shutdown)
{
itemAvailable.wait(lock);
while (!queue.empty())
{
Progress progress = queue.front();
queue.pop();
// Do lengthy operation with progress
}
}
}
. 밀어 넣기가 진행 중이고 대기열에 항목이 두 개 이상있는 경우 Finish 메서드가 호출되면 모든 항목이 팝되지 않습니다. 몇 가지 추가 정보에서 잠깐만 기다려야 겠지만 잠김은 대기열을 보호하지 않고 상태 변수를 보호하기위한 것입니다. –