/ / правилния начин да пишете на файл от различни нишки (използвайки Qt c ++) - c ++, multithreading, qt, заключване

правилния начин да пишете на файл от различни нишки (използвайки Qt c ++) - c ++, multithreading, qt, заключване

аз имам нишка басейн, които създават нишки всеки служител нишка изчислява някои работа и когато тя свърши той пише резултата в файл, има само 1 резултат файл, че всеки работник нишка трябва да пиша.
сега въпросът ми е как гарантирам, че тамняма да има никакви брави или липсващи данни за писане във файла, където се разпределят нишки, които се опитват да пишат в един файл - каква е правилната стратегия за такъв сценарий?
mybe запази всички в паметта? или отрицателни резултати

im използвайки вече QThreadPool framework и трябва да намеря решение с него.
също така аз се скитат, пише ли на един файл от работник нишки, аз ще трябва да използват
singleton файлов мениджър или статичен клас, е ли добра идея? за многонишково приложение?

Отговори:

5 за отговор № 1

Така че имате много конкуриращи се теми за един споделен ресурс. Това предизвиква синхронизиращ примитив от някакъв вид, например а мутекс.

Тук (не-Qt специфичен) код, показващ 10 теми едновременно писане на един файл.На странична бележка, C + + 11 въведе много награди като std::mutexstd::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;
};