[英]Cannot write concurrently to file from more than 5 threads c++
我正在for循環中啟動20個線程,以將其寫入這樣的文件:
for (FileSearcher & searcher : searchers)
{
searcher.start([&sf](std::string & fileName, int & id)
{
for (int i = 1; i < 100; i++)
{
//sf << "T " << id << " " << fileName << i << "\n";
std::string msg("T ");
msg += std::to_string(id);
msg += " ";
msg += fileName;
msg += std::to_string(i);;
msg += "\n";
sf.writeLine(msg);
}
});
searcher.start()函數啟動線程,該線程將執行作為參數傳遞的lambda。 sf對象擁有由線程寫入的實際文件和由sf.writeLine()中的std :: lock_guard鎖定的互斥鎖。
問題在於,只有5個線程正在同時向文件寫入數據,並且其中一個線程完成了作業之后,下一個線程開始與尚未完成的其他4個線程同時寫入文件。 依此類推,直到20個線程全部完成。
為什么會這樣呢? 難道不是所有20個線程都同時寫入文件,而不是一次寫入5個線程?
這是完整的代碼:
主要:
#include <iostream>
#include "FileSearcher.h"
#include "SafeFileStream.h"
int main()
{
SafeFileStream sf("D:\\x.txt");
//sf.writeLine("hellow");
FileSearcher searchers[20];
for (int j = 0; j < 20; j++)
{
searchers[j].setFileName("Some file name.txt");
searchers[j].setId(j);
}
for (FileSearcher & searcher : searchers)
{
searcher.start([&sf](std::string & fileName, int & id)
{
for (int i = 1; i < 100; i++)
{
//sf << "T " << id << " " << fileName << i << "\n";
std::string msg("T ");
msg += std::to_string(id);
msg += " ";
msg += fileName;
msg += std::to_string(i);;
msg += "\n";
sf.writeLine(msg);
}
});
}
for (FileSearcher & searcher : searchers)
{
searcher.join();
}
return 0;
}
FileSearcher.h
#include <thread>
#include <string>
#include <functional>
#include <fstream>
class FileSearcher {
private:
std::unique_ptr<std::thread> searcher;
std::string fileName;
std::ifstream inputFile;
int id;
public:
FileSearcher();
FileSearcher(const int &, const std::string &);
~FileSearcher();
void start(std::function<void(std::string &, int &)>);
void join();
void setFileName(const std::string &);
void setId(const int &);
};
FileSearcher.cpp
#include "FileSearcher.h"
FileSearcher::FileSearcher() {}
FileSearcher::FileSearcher(const int & id, const std::string & fileName)
{
this->fileName = fileName;
this->id = id;
}
FileSearcher::~FileSearcher()
{
if (this->searcher->joinable())
{
this->searcher->join();
}
}
void FileSearcher::setFileName(const std::string & fileName)
{
this->fileName = fileName;
}
void FileSearcher::setId(const int & id)
{
this->id = id;
}
void FileSearcher::start(std::function<void(std::string &, int & id)> searchingMethod)
{
this->inputFile.open(this->fileName);
this->searcher = std::unique_ptr<std::thread>(new std::thread(searchingMethod, std::ref(this->fileName), std::ref(this->id)));
}
void FileSearcher::join()
{
if (this->searcher->joinable())
{
this->searcher->join();
}
}
SafeFileStream.h
#include <fstream>
#include <string>
#include <mutex>
#include <iostream>
class SafeFileStream
{
private:
std::ofstream outputFile;
std::string fileName;
std::mutex mu;
std::unique_ptr<std::lock_guard<std::mutex>> lockGuard;
std::unique_lock<std::mutex> uniqueLocker;
std::unique_ptr<std::thread> safeQueueHandler;
public:
SafeFileStream(std::string);
SafeFileStream(SafeFileStream&&);
~SafeFileStream();
template <typename T> void writeLine(T);
template <typename T> void write(T msg);
};
SafeFileStream::SafeFileStream(std::string fileName) : fileName(fileName)
{
this->outputFile.open(fileName);
}
SafeFileStream::SafeFileStream(SafeFileStream&& sfFileStream)
{
this->fileName = sfFileStream.fileName;
}
SafeFileStream::~SafeFileStream()
{
this->outputFile.close();
}
template <typename T> void SafeFileStream::writeLine(T msg)
{
std::lock_guard<std::mutex> lockGuard(this->mu);
this->outputFile << msg << "\n";
}
template <typename T> void SafeFileStream::write(T msg)
{
std::lock_guard<std::mutex> lockGuard(this->mu);
this->outputFile << msg;
}
您無法確定上下文切換的時間。 這取決於操作系統。 但是您可以“詢問”上下文切換到操作系統的情況。
調用std :: this_thread :: yield(); 在sf.writeLine(msg);之后
for (FileSearcher & searcher : searchers)
{
searcher.start([&sf](std::string & fileName, int & id)
{
for (int i = 1; i < 100; i++)
{
//sf << "T " << id << " " << fileName << i << "\n";
std::string msg("T ");
msg += std::to_string(id);
msg += " ";
msg += fileName;
msg += std::to_string(i);;
msg += "\n";
sf.writeLine(msg);
std::this_thread::yield();
}
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.