c++獲取系統時間戳的方法

在程序中,我們經常需要獲取當前的時間戳到毫秒甚至微妙級,但是頻繁的調用API會對程序的性能有些許影響,並且要還要考慮不同平臺的影響。參考大佬https://www.jianshu.com/p/c9b775d831fb的實現,積累下關於頻繁獲取時間戳的知識。
實現的思路是:

  • 設置兩個原子變量,分別記錄當前的毫秒和微妙的時間戳。
  • 啓動一個時間的線程,每隔一個時間間隔,獲取當前最新的時間戳,並更新兩個原子變量。注意,線程爲分離屬性。
  • 當獲取最新時間時,只要將對應的原子變量值返回就可以了。
  • 在linux平臺下使用性能最好的gettimeofday(),在windows平臺下,使用std::chrono.
#include <atomic>
#include <chrono>
#include <thread>
#include <functional>
using namespace std;

#ifdef _WIN32
#include <windows.h>
#else
#include <sys/time.h>

#endif //_WIN32

//該類藉助RAII思想,使傳入的task對象可以成對進行,而不考慮釋放的問題
class onceToken {
public:
	typedef function<void(void)> task;
	onceToken(const task &onConstructed, const task &onDestructed = nullptr) {
		if (onConstructed) {
			onConstructed();
}
		_onDestructed = onDestructed;
	}
	onceToken(const task &onConstructed, task &&onDestructed) {
		if (onConstructed) {
			onConstructed();
		}
		_onDestructed = std::move(onDestructed);
	}
	~onceToken() {
		if (_onDestructed) {
			_onDestructed();
		}
	}
private:
	onceToken();
	onceToken(const onceToken &);
	onceToken(onceToken &&);
	onceToken &operator =(const onceToken &)=delete;
	onceToken &operator =(onceToken &&) = delete;
	task _onDestructed;
};

static inline uint64_t getCurrentMicrosecondOrigin() {
#if !defined(_WIN32)
	struct timeval tv;
	gettimeofday(&tv, NULL);
	return tv.tv_sec * 1000000LL + tv.tv_usec;
#else
	return  std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
#endif
}

static atomic<uint64_t> s_currentMicrosecond(getCurrentMicrosecondOrigin());
static atomic<uint64_t> s_currentMillisecond(getCurrentMicrosecondOrigin() / 1000);

static inline bool initMillisecondThread() {
	static std::thread s_thread([]() {
		uint64_t now;
		while (true) {
			now = getCurrentMicrosecondOrigin();
			s_currentMicrosecond.store(now, memory_order_release);
			s_currentMillisecond.store(now / 1000, memory_order_release);
#if !defined(_WIN32)
			//休眠0.5 ms
			usleep(500);
#else
			Sleep(1);
#endif
		}
	});
	static onceToken s_token([]() {
		s_thread.detach();
	});
	return true;
}

uint64_t getCurrentMillisecond() {
	static bool flag = initMillisecondThread();
	return s_currentMillisecond.load(memory_order_acquire);
}

uint64_t getCurrentMicrosecond() {
	static bool flag = initMillisecondThread();
	return s_currentMicrosecond.load(memory_order_acquire);
}

#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
	while (1)
	{
		cout << "-----" << getCurrentMillisecond() << endl;
		cout << "*****" << getCurrentMicrosecond() << endl;
		Sleep(1000);
	}
	getchar();
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章