【c++】【多線程】類對象創建時線程自啓動 原

在某些場景下,需要週期性的執行耗時操作,比如寫文件。這種場景,有兩個需求點:

1.執行一次任務比較耗時,不能影響主業務性能。

2.該任務週期性執行。

這種場景:可以每次在執行任務時啓動一個線程,但是這樣做,當任務執行比較頻繁時,需要多次創建線程,這樣會有不小的由於線程多次創建引起的性能損耗。所以,可以採用如下方案:

啓動一個後臺線程,當有任務時,被喚醒,沒有任務時,線程睡眠。

#pragma once
#include <mutex>
#include <condition_variable>
#include <string>
#include <vector>
#include <thread>
#include <iostream>
using namespace std;
class  SingleInstance
{
public:
	static SingleInstance *getInstance();
	static void start(void * arg);
	void addMsg(string msg);
private:
	SingleInstance();
	~ SingleInstance() = default;

private:
	static SingleInstance * instance;
	static mutex instanceLock;
	vector<string> msg;
	condition_variable msgCV;
	mutex msgLock;
};

實現代碼如下:

#include "SingleInstance.h"
SingleInstance * SingleInstance::instance = nullptr;
mutex SingleInstance::instanceLock;

SingleInstance *SingleInstance::getInstance()
{
	if (instance == nullptr) {
		lock_guard<mutex> lk(instanceLock);
		if (instance == nullptr) {
			instance = new SingleInstance();
		}
	}

	return instance;
}

SingleInstance::SingleInstance() 
{
	thread t(SingleInstance::start,this);
	t.detach(); // 作爲後臺線程運行
}

void SingleInstance::start(void *args)
{
	SingleInstance * instance = static_cast<SingleInstance *>(args);
	if(instance == nullptr){
		return;
	}
	while (1) {
		unique_lock<mutex> lk(instance->msgLock);
		while (instance->msg.empty())
		{
			instance->msgCV.wait(lk);
		}
		cout <<"server receive msg is:"<< instance->msg[0] << endl;
		instance->msg.clear();
	}
}

void SingleInstance::addMsg(string msg)
{
	lock_guard<mutex> lk(this->msgLock);
	this->msg.push_back(msg);
	this->msgCV.notify_one();
}

測試代碼如下:

#include <iostream>
#include <string>
#include <map>
#include "LogTime.h"
#include "SingleInstance.h"
using namespace std;




int main(int argc, int * argv[])
{

	SingleInstance * instance = SingleInstance::getInstance();

	instance->addMsg("hello");

	for (int i = 0; i < 1e5; i++);

	instance->addMsg("world");

	system("pause");

}

測試結果如下:

尤其是對於有特殊需求的日誌這種場景,可以採用這種方式。當然,在單條日誌數據量不太的場景下,可以先將日誌寫在緩存裏,當緩存滿了之後,再將日誌發送給sever進行寫文件

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章