C++ 无法从超过5个线程c+;同时写入文件+;
我将在for循环中启动20个线程,以写入如下文件:C++ 无法从超过5个线程c+;同时写入文件+;,c++,multithreading,C++,Multithreading,我将在for循环中启动20个线程,以写入如下文件: for (FileSearcher & searcher : searchers) { searcher.start([&sf](std::string & fileName, int & id) { for (int i = 1; i < 100; i++) { //sf << "T " << id <&
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(文件搜索器和搜索器:搜索器)
{
searcher.start([&sf](标准::字符串和文件名,int&id)
{
对于(int i=1;i<100;i++)
{
//sf您无法确定上下文切换的时间。
这取决于操作系统。
但是您可以“询问”切换到操作系统的上下文
在sf.writeLine(msg)之后调用std::this_thread::yield()
for(文件搜索器和搜索器:搜索器)
{
searcher.start([&sf](标准::字符串和文件名,int&id)
{
对于(int i=1;i<100;i++)
{
//如果您只有5个内核?定义“只有5个线程同时写入文件”。锁似乎在任何给定时间只允许一个线程写入文件。@Siyuan Ren我有4个线程cores@SamVarshavchik“只有5个线程同时写入文件”-我的意思是5个线程同时写入文件。其他15个线程是被动的。如果其中一个主动线程完成写入,则其中一个被动线程激活并开始与其他4个主动线程同时写入。据我所知,该标准对“公平性”没有任何保证在线程调度中,或者等待互斥锁的线程将以任何特定顺序获得互斥锁的所有权。
#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;
}
#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 &);
};
#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();
}
}
#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;
}
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();
}
});