【发布时间】:2018-05-07 08:46:52
【问题描述】:
最近我开始学习 C++ 11。我在大学时只学习了一小段时间 C/C++。我来自另一个生态系统(Web 开发),所以你可以想象我对 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!
到目前为止我还没有看到任何垃圾......
【问题讨论】:
-
正如许多人(包括我)所指出的那样,您的日志是按顺序运行的,而不是并行运行的,因为您在生成每个线程后立即加入。
-
是的,我错过了,你们是对的 :)
标签: c++ multithreading c++11 make-shared