Недавно я начал изучать C++ 11. Я изучал C/C++ в течение короткого периода времени, когда учился в колледже. Я пришел из другой экосистемы (веб-разработка), поэтому, как вы можете себе представить, я относительно новичок в C++.
На данный момент я изучаю потоки и то, как можно выполнить ведение журнала из нескольких потоков с помощью одного писателя (дескриптора файла). Поэтому я написал следующий код на основе руководств и чтения различных статей.
- Мой первый вопрос и просьба заключались бы в том, чтобы указать на любые плохие практики/ошибки, которые я упустил из виду (хотя код работает с VC 2015).
- Во-вторых, и это то, что меня больше всего беспокоит, это то, что я не закрываю дескриптор файла, и я не уверен, что это вызывает какие-либо проблемы. Если это так, когда и как было бы наиболее подходящим способом закрыть его?
- Наконец, поправьте меня, если я ошибаюсь, я не хочу «приостанавливать» поток, пока другой поток пишет. Я пишу построчно каждый раз. Есть ли случай, когда вывод в какой-то момент испортится?
Большое спасибо за ваше время, ниже приведен источник (в настоящее время в учебных целях все находится внутри main.cpp
).
#include <iostream>
#include <fstream>
#include <thread>
#include <string>
static const int THREADS_NUM = 8;
class Logger
{
public:
Logger(const std::string &path) : filePath(path)
{
this->logFile.open(this->filePath);
}
void write(const std::string &data)
{
this->logFile << data;
}
private:
std::ofstream logFile;
std::string filePath;
};
void spawnThread(int tid, std::shared_ptr<Logger> &logger)
{
std::cout << "Thread " + std::to_string(tid) + " started" << std::endl;
logger->write("Thread " + std::to_string(tid) + " was here!\n");
};
int main()
{
std::cout << "Master started" << std::endl;
std::thread threadPool[THREADS_NUM];
auto logger = std::make_shared<Logger>("test.log");
for (int i = 0; i < THREADS_NUM; ++i)
{
threadPool[i] = std::thread(spawnThread, i, logger);
threadPool[i].join();
}
return 0;
}
PS1: в этом сценарии всегда будет открыт только 1 дескриптор файла для потоков для регистрации данных.
PS2: В идеале дескриптор файла должен закрываться прямо перед выходом из программы... Следует ли это делать в деструкторе Logger?
ОБНОВЛЕНИЕ
Текущий вывод с 1000 потоков следующий:
Thread 0 was here!
Thread 1 was here!
Thread 2 was here!
Thread 3 was here!
.
.
.
.
Thread 995 was here!
Thread 996 was here!
Thread 997 was here!
Thread 998 was here!
Thread 999 was here!
мусора пока не вижу...