一种基于C++的日志类建立及其在单线程和多线程环境下的输出或打印方法
thread(线程)可以用来解决以下问题:
1.并发性:线程可以在一个应用程序中同时执行多个任务,从而提高应用程序的并发性。例如,在一个网络服务器应用程序中,可以使用多个线程来同时处理来自多个客户端的请求。
2.响应性:使用线程可以使应用程序更加响应用户的操作。例如,在一个图形用户界面(GUI)应用程序中,可以将用户界面更新的任务放在一个线程中,而将其他计算密集型任务放在另一个线程中,这样可以保持用户界面的流畅性。
3.数据共享:线程可以让多个任务共享同一份数据,从而简化数据共享和通信的实现。例如,在一个多线程的计算程序中,可以将输入数据存储在共享的数据结构中,并让多个线程同时对其进行读取和处理。
4.并行计算:线程可以用于实现并行计算,从而加速程序的执行速度。例如,在一个使用多线程的计算密集型应用程序中,可以将任务拆分为多个子任务,并使用多个线程同时执行这些子任务,以提高计算速度。
5.任务分解:线程可以用于将一个复杂的任务拆分为多个子任务,并分配给不同的线程来并行执行。这种方式可以提高任务的执行效率和速度。例如,在一个大规模数据处理的应用程序中,可以将数据分割成多个块,并使用多个线程同时处理这些数据块。
对于单线程的C++程序来说,日志类只需要存在一个全局类,代码如下:
#include <iostream>
#include <string>
using namespace std;
class Log {
public:
Log() {};
Log(const Log& log) = delete;
Log& operator=(const Log& log) = delete;
static Log& GetInstance() {
// static Log log; 懒汉模式,提前声明对象
static Log* log = nullptr; //饿汉模式,提取不声明对象,需要使用时进行声明
if (!log) log = new Log;
return *log;
}
void PrintLog(string msg)
{
cout << __TIME__ << " : " << msg << endl;/*打印输出,或者是存入日志文件中*/
}
};
int main(){
Log::GetInstance().PrintLog("打印日志");
return 0;
}
以上方式适用于单线程模式,如果是多线程模式,建议代码如下:
#include <iostream>
#include <thread>
#include <string>
using namespace std;
static once_flag once;
class Log {
public:
Log() {};
Log(const Log& log) = delete;
Log& operator=(const Log& log) = delete;
static Log* log; /*静态变量声明*/
static Log& GetInstance() {
call_once(once, init);/*保证在多个线程中只执行一次*/
return *log;
}
static void init()
{
if (!log) log = new Log;
}
void PrintLog(string msg)
{
cout << __TIME__ << " : " << msg << endl;
}
};
Log* Log::log = nullptr;/*静态变量的定义*/
void PrintLog(string msg) {
Log::GetInstance().PrintLog(msg);
int main(){
/*保证在多线程的情况下,log类只new了一次*/
thread tt1(PrintLog, "日志输出1");
thread tt2(PrintLog, "日志输出2");
thread tt3(PrintLog, "日志输出3");
tt1.join();
tt2.join();
tt3.join();
return 0;
}
call_once()只能在线程中使用,在main中调用会报错