다운로드 항목에 대해 여러 스레드에서 여러 종류의 처리를 수행하는 다운로더 응용 프로그램이 있습니다. 일부 스레드는 입력 데이터를 분석하고 일부는 다운로드, 추출, 상태 저장 등을 수행합니다. 따라서 스레드의 각 유형은 특정 데이터 구성원에서 작동하고 이러한 스레드 중 일부는 동시에 실행될 수 있습니다. 다운로드 항목은 다음과 같이 설명 할 수 있습니다.다중 스레드 처리 중에 데이터 저장
class File;
class Download
{
public:
enum State
{
Parsing, Downloading, Extracting, Repairing, Finished
};
Download(const std::string &filePath): filePath(filePath) { }
void save()
{
// TODO: save data consistently
StateFile f; // state file for this download
// save general download parameters
f << filePath << state << bytesWritten << totalFiles << processedFiles;
// Now we are to save the parameters of the files which belong to this download,
// (!) but assume the downloading thread kicks in, downloads some data and
// changes the state of a file. That causes "bytesWritten", "processedFiles"
// and "state" to be different from what we have just saved.
// When we finally save the state of the files their parameters don't match
// the parameters of the download (state, bytesWritten, processedFiles).
for (File *f : files)
{
// save the file...
}
}
private:
std::string filePath;
std::atomic<State> state = Parsing;
std::atomic<int> bytesWritten = 0;
int totalFiles = 0;
std::atomic<int> processedFiles = 0;
std::mutex fileMutex;
std::vector<File*> files;
};
이 데이터를 일관되게 저장하는 방법을 궁금합니다. 예를 들어, 처리 된 파일의 상태와 수는 이미 저장되었을 수 있으며 파일 목록을 저장합니다. 한편 다른 스레드는 파일의 상태를 변경하여 결과 파일의 수나 다운로드 상태를 변경하여 저장된 데이터의 일관성을 유지할 수 있습니다.
첫 번째 생각은 모든 데이터 멤버에 단일 뮤텍스를 추가하고 중 어느 하나라도에 액세스 할 때마다 잠그는 것입니다. 그러나 대부분의 시간 스레드가 다른 데이터 멤버에 액세스하고 저장하는 데 몇 분 안에 단 한 번만 발생하므로 비효율적 일 수 있습니다.
다중 스레드 프로그래밍에서는 이러한 작업이 다소 일반적인 것처럼 보입니다. 경험있는 사람들이 더 나은 방법을 제안 할 수 있기를 바랍니다.
* "마음에 오는 첫 번째 아이디어는 하나의 뮤텍스를 추가하는 것입니다 : 여기
어떻게 동시에 다운로드, 구문 분석, 추출 및 저장해야하는 경우 수행하는 샘플 큐에 대한 코드입니다 모든 데이터 멤버에 대해 액세스하고 그 중 하나에 액세스 할 때마다 잠그십시오. "* - 왜 여러 뮤텍스를 사용할 수없고 개인 회원에게 액세스를 잠글 수 있습니까? 그리고 클래스를 여러 개의 다른 클래스로 나눠서 각 스레드가 완료되고 부분 결과가 최종 결과로 모아 질 때까지 조용하게 자체 데이터 조각에서 작업 할 수 있도록하는 것이 어떻습니까? –글쎄, 위에서 설명한 것처럼 개별 멤버를 잠그더라도 전체 데이터 세트가 일관성없이 저장되는 것을 방지하지 못합니다. 예 : 저장된 다운로드 상태 및 처리 된 파일 수가 저장된 파일 목록과 일치하지 않을 수 있습니다. 글쎄, 스레드가 동일한 데이터 멤버를 사용할 수 있습니다. 나는 단지 그들이 모두를 사용할 수는 없다는 것을 의미했습니다. – mentalmushroom