muduo网络库学习笔记(1):Timestamp类
来源:互联网 发布:一起作业网刷学豆软件 编辑:程序博客网 时间:2024/06/07 10:59
时间戳一般用来唯一地标识某一刻的时间,通常是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总毫秒数。
muduo网络库对时间戳Timestamp类也进行了封装。
Timestamp类类图:
由类图可知,Timestamp类的参数有一个常量kMicroSecondsPerSecond表示每秒所对应的微秒数,成员变量microSecondsSinceEpoch_表示到1970-01-01 00:00:00 UTC的微秒数。成员函数包括swap()交换操作,toString()、toFormattedString()将时间转换为string类型或指定格式,valid()判断Timestamp是否有效,invalid()返回一个无效的Timestamp,now()返回当前时间的Timestamp,secondsSinceEpoch()/microSecondsSinceEpoch()返回到1970-01-01 00:00:00 UTC的秒数/微秒数。
代码中的一些要点如下:
(1)Timestamp类继承自boost::less_than_comparable <T>模板类
只要实现 <,即可自动实现>,<=,>=
(2)使用到了BOOST_STATIC_ASSERT,编译时断言
我们一般使用的assert是运行时断言,用一个小例子来理解BOOST_STATIC_ASSERT:
#include <boost/static_assert.hpp>class Timestamp{private: int64_t microSecondsSinceEpoch_;};// 编译时断言通过// BOOST_STATIC_ASSERT(sizeof(Timestamp) == sizeof(int64_t));// 编译时断言失败BOOST_STATIC_ASSERT(sizeof(int) == sizeof(short));int main(void){ return 0;}
编译上述例子,在编译时就会报错
(3)gmtime和gmtime_r函数
用法:
struct tm *gmtime(const time_t *timep);
struct tm *gmtime_r(const time_t *timep, struct tm *result);
gmtime(线程不安全的)是把日期和时间转换为格林威治(GMT)时间的函数。将参数timep 所指的time_t 结构中的信息转换成真实世界所使用的时间日期表示方法,然后将结果由结构tm返回。使用gmtime后要立即处理结果,否则返回的指针指向的内容可能会被覆盖。一个好的方法是使用gmtime_r(线程安全的),gmtime_r()函数功能与此相同,但是它可以将数据存储到用户提供的结构体中,由于使用了用户分配的内存,是不会出错的。
节选muduo源码中的使用示例:
string Timestamp::toFormattedString() const{ char buf[32] = {0}; time_t seconds = static_cast<time_t>(microSecondsSinceEpoch_ / kMicroSecondsPerSecond); // 秒数 int microseconds = static_cast<int>(microSecondsSinceEpoch_ % kMicroSecondsPerSecond); struct tm tm_time; // 微秒数 // 把time_t结构中的信息转换成真实世界所使用的时间日期,存储在tm_time结构中 gmtime_r(&seconds, &tm_time); // 格式化输出时间戳 snprintf(buf, sizeof(buf), "%4d%02d%02d %02d:%02d:%02d.%06d", tm_time.tm_year + 1900, tm_time.tm_mon + 1, tm_time.tm_mday, tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec, microseconds); return buf;}
(4)使用PRId64
int64_t用来表示64位整数,在32位系统中是long long int,在64位系统中是long int,所以打印int64_t的格式化方法是:
printf(“%ld”, value); // 64bit OSprintf("%lld", value); // 32bit OS
这种做法是不可移植的。
跨平台的做法:
// C++使用PRID64,需要两步:// 包含头文件:<inttypes.h>// 定义宏:__STDC_FORMAT_MACROS,可以通过编译时加-D__STDC_FORMAT_MACROS,或者在包含文件之前定义这个宏。#define __STDC_FORMAT_MACROS#include <inttypes.h>#undef __STDC_FORMAT_MACROS printf("%" PRId64 "\n", value);
(5)对象语义和值语义
值语义:值语义是指对象的拷贝与原对象无关,拷贝之后就与原对象脱离关系,彼此独立互不影响(深拷贝)。C++中的内置类型都是值语义,比如说int。值语义的一个巨大好处是生命期管理很简单。
对象语义:对象语义指的是面向对象意义下的对象。
对象拷贝要么是禁止的(Noncopyable) ,要么一个对象被系统标准的复制方式复制后,与被复制的对象之间依然共享底层资源,对任何一个的改变都将改变另一个(浅拷贝)。比如,Thread 是对象语义,拷贝 Thread 是无意义的,也是被禁止的:因为 Thread 代表线程,拷贝一个Thread对象并不能让系统增加一个一模一样的线程。
对象语义对象生命期不容易控制,一般通过智能指针来解决。智能指针实际上是将对象语义转化为值语义,利用局部对象(智能指针)的确定性析构,智能指针包括auto_ptr, shared_ptr, weak_ptr, scoped_ptr。
- muduo网络库学习笔记(1):Timestamp类
- muduo网络库学习之Timestamp类、AtomicIntegerT 类封装中的知识点
- muduo 3 网络库学习之Timestamp类、AtomicIntegerT 类封装中的知识点
- muduo网络库学习笔记(3):Thread类
- muduo网络库学习笔记(12):TcpServer和TcpConnection类
- muduo网络库源码学习————Timestamp.cc
- muduo库的Timestamp类剖析
- muduo网络库学习笔记(2):原子性操作
- muduo网络库学习笔记(4):互斥量和条件变量
- muduo网络库学习笔记(5):线程池的实现
- muduo网络库学习笔记(6):单例类(线程安全的)
- muduo网络库学习笔记(7):线程特定数据
- muduo网络库学习笔记(10):定时器的实现
- muduo网络库学习笔记(8):高效日志类的封装
- muduo网络库学习之muduo_http 库涉及到的类
- muduo网络库学习之muduo_inspect 库涉及到的类
- muduo网络库学习之muduo_inspect 库涉及到的类
- 【muduo网络库学习】之Acceptor类分析
- python cmp()函数
- Linux下进入单用户模式,修改文件,密码
- topk 问题
- spring中StrSubstitutor更换表达式符号和忽略大小写StrLookup
- zzuli 1899: 985的最大和难题
- muduo网络库学习笔记(1):Timestamp类
- logcat输出
- SpringMVC上传超过2M文件时不能正常返回异常信息到页面
- JVM调优总结
- Python终端显示彩色字符(封装了Colored类)
- js:跳转和AJAX
- 深入理解Java的接口和抽象类
- Java使用Jetty实现嵌入式Web服务器及Servlet容器
- 微信Demo导入遇到的问题