аз имам нишка басейн, които създават нишки всеки служител нишка изчислява някои работа и когато тя свърши той пише резултата в файл, има само 1 резултат файл, че всеки работник нишка трябва да пиша.
сега въпросът ми е как гарантирам, че тамняма да има никакви брави или липсващи данни за писане във файла, където се разпределят нишки, които се опитват да пишат в един файл - каква е правилната стратегия за такъв сценарий?
mybe запази всички в паметта? или отрицателни резултати
im използвайки вече QThreadPool framework и трябва да намеря решение с него.
също така аз се скитат, пише ли на един файл от работник нишки, аз ще трябва да използват
singleton файлов мениджър или статичен клас, е ли добра идея? за многонишково приложение?
Отговори:
5 за отговор № 1Така че имате много конкуриращи се теми за един споделен ресурс. Това предизвиква синхронизиращ примитив от някакъв вид, например а мутекс.
Тук (не-Qt специфичен) код, показващ 10 теми едновременно писане на един файл.На странична бележка, C + + 11 въведе много награди като std::mutex
(и std::thread
също така, така че може да помогне за елиминирането на специфичен за Qt конец на резби).
#include <fstream>
#include <mutex>
#include <thread>
#include <vector>
std::mutex m;
std::ofstream file;
int main() {
file.open("file.txt");
std::vector<std::thread> workers;
for (int i = 0; i < 10; ++i) {
workers.push_back(std::thread([=i] {
for (int j = 0; j < 10; ++j) {
std::lock_guard<std::mutex> lock(m);
file << "thread " << i << ": " << j << endl;
}
}));
}
for (auto& worker : workers) {
worker.join();
}
file.close();
return 0;
}
Разбира се, ако имате много места във вашиякод, който има достъп до споделения ресурс, е по-добре да го капсулира, заедно с mutex, в някой клас "accessor", който ще управлява всички промени в състоянието на ресурса.
Послепис Ако не сте на C ++ 11 компилатор, можете да го използвате boost::mutex
или Qt-специфична обвивка на мутекс. Най-важното е, че се нуждаете някои примитив на синхронизиране, свързан със споделения ресурс.
2 за отговор № 2
Както предполагам, вие сами сте Runnable
, получени от QRunnable
Можете да предавате известна контекстна информация при изграждането на вашето Runnable
клас. Трябва да преминете устройството, за да пишете и mutex
за заключване на устройството, например.
class Runnable: public QRunnable
{
public:
Runnable(QIOdevice* device, QMutex* mutex):_d(device), _m(mutex){}
void run()
{
saveInFile();
}
private:
void saveInFile()
{
QMutexLocker lock(_m);
//now only one thread can write to file in the same moment of time
device->write(...);
}
QIOdevice* _d;
QMutex* _m;
};