muduo_base时间戳相关模块

使用的muduo源码为2.0.2版本。

muduo_base时间戳相关模块_第1张图片

muduo_base时间戳相关模块_第2张图片

muduo_base时间戳相关模块_第3张图片

muduo_base 时间戳相关代码

先从muduo_base下的UTC时间戳文件开始学习。看下Timestamp.ccTimestamp.h以及测试代码Timestamp_unittest.cc

muduo_base时间戳相关模块_第4张图片

这个less_than_comparable要求实现<,可自动实现><=>=(通过模板元类型推演)。这个less_than_comparableboost提供,就不去剖析其实现,只需要实现<运算符。在Tmestamp.h中已经对其进行实现,代码如下:

muduo_base时间戳相关模块_第5张图片

接下来我们先去编译一个Timestamp.ccTimestamp.h,发现Timestamp.h中包含了另外两个头文件copyable.hTypes.h,将四个文件一并拷贝至新的目录文件,创建一个mymuduo文件夹,在该文件夹下创建muduo文件夹,进入muduo,将原始muduo网络库中的build.sh和与之同级的CMakeLists.txt均拷贝至mymuduo/muduo/文件目录下,并在该文件目录mymuduo/muduo/文件夹目录下创建新文件夹muduo,这个muduo文件夹将要存放basenet代码,所以在该目录下再创建base文件夹,具体文件结构如下图:

muduo_base时间戳相关模块_第6张图片

图中其余文件均为编译生成的文件,要想编译成功,先修改两个拷贝过来的CMakeLists.txt,把不需要的文件先注释掉,两个CMakeLists.txt内容分别如下:
mymuduo/muduo/CMakeLists.txt

cmake_minimum_required(VERSION 2.6)

project(muduo C CXX)

enable_testing()

if(NOT CMAKE_BUILD_TYPE)
  set(CMAKE_BUILD_TYPE "Release")
endif()

# only build examples if this is the main project
if(CMAKE_PROJECT_NAME STREQUAL "muduo")
  option(MUDUO_BUILD_EXAMPLES "Build Muduo examples" ON)
endif()

set(CXX_FLAGS
 -g
 # -DVALGRIND
 -DCHECK_PTHREAD_RETURN_VALUE
 -D_FILE_OFFSET_BITS=64
 -Wall
 -Wextra
 -Werror
 -Wconversion
 -Wno-unused-parameter
 -Wold-style-cast
 -Woverloaded-virtual
 -Wpointer-arith
 -Wshadow
 -Wwrite-strings
 -march=native
 # -MMD
 -std=c++11
 -rdynamic
 )
if(CMAKE_BUILD_BITS EQUAL 32)
  list(APPEND CXX_FLAGS "-m32")
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
  list(APPEND CXX_FLAGS "-Wno-null-dereference")
  list(APPEND CXX_FLAGS "-Wno-sign-conversion")
  list(APPEND CXX_FLAGS "-Wno-unused-local-typedef")
  list(APPEND CXX_FLAGS "-Wthread-safety")
  list(REMOVE_ITEM CXX_FLAGS "-rdynamic")
endif()
string(REPLACE ";" " " CMAKE_CXX_FLAGS "${CXX_FLAGS}")

set(CMAKE_CXX_FLAGS_DEBUG "-O0")
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG")
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)

find_package(Boost REQUIRED)
find_package(Protobuf)
find_package(CURL)
find_package(ZLIB)
find_path(CARES_INCLUDE_DIR ares.h)
find_library(CARES_LIBRARY NAMES cares)
find_path(MHD_INCLUDE_DIR microhttpd.h)
find_library(MHD_LIBRARY NAMES microhttpd)
find_library(BOOSTTEST_LIBRARY NAMES boost_unit_test_framework)
find_library(BOOSTPO_LIBRARY NAMES boost_program_options)
find_library(BOOSTSYSTEM_LIBRARY NAMES boost_system)
find_path(TCMALLOC_INCLUDE_DIR gperftools/heap-profiler.h)
find_library(TCMALLOC_LIBRARY NAMES tcmalloc_and_profiler)
find_path(HIREDIS_INCLUDE_DIR hiredis/hiredis.h)
find_library(HIREDIS_LIBRARY NAMES hiredis)
find_path(GD_INCLUDE_DIR gd.h)
find_library(GD_LIBRARY NAMES gd)
find_program(THRIFT_COMPILER thrift)
find_path(THRIFT_INCLUDE_DIR thrift)
find_library(THRIFT_LIBRARY NAMES thrift)

if(CARES_INCLUDE_DIR AND CARES_LIBRARY)
  message(STATUS "found cares")
endif()
if(CURL_FOUND)
  message(STATUS "found curl")
endif()
if(PROTOBUF_FOUND)
  message(STATUS "found protobuf")
endif()
if(TCMALLOC_INCLUDE_DIR AND TCMALLOC_LIBRARY)
  message(STATUS "found tcmalloc")
endif()
if(ZLIB_FOUND)
  message(STATUS "found zlib")
endif()
if(HIREDIS_INCLUDE_DIR AND HIREDIS_LIBRARY)
  message(STATUS "found hiredis")
endif()
if(GD_INCLUDE_DIR AND GD_LIBRARY)
  message(STATUS "found gd")
endif()
if(THRIFT_COMPILER AND THRIFT_INCLUDE_DIR AND THRIFT_LIBRARY)
  message(STATUS "found thrift")
endif()

include_directories(${Boost_INCLUDE_DIRS})

include_directories(${PROJECT_SOURCE_DIR})

string(TOUPPER ${CMAKE_BUILD_TYPE} BUILD_TYPE)
message(STATUS "CXX_FLAGS = " ${CMAKE_CXX_FLAGS} " " ${CMAKE_CXX_FLAGS_${BUILD_TYPE}})

add_subdirectory(muduo/base)
# add_subdirectory(muduo/net)
# 
# if(MUDUO_BUILD_EXAMPLES)
#   add_subdirectory(contrib)
#   add_subdirectory(examples)
# else()
#   if(CARES_INCLUDE_DIR AND CARES_LIBRARY)
#     add_subdirectory(examples/cdns)
#   endif()
# endif()

mymuduo/muduo/muduo/base/CMakeLists.txt

set(base_SRCS
  # AsyncLogging.cc
  # Condition.cc
  # CountDownLatch.cc
  # CurrentThread.cc
  # Date.cc
  # Exception.cc
  # FileUtil.cc
  # LogFile.cc
  # Logging.cc
  # LogStream.cc
  # ProcessInfo.cc
  Timestamp.cc
  # Thread.cc
  # ThreadPool.cc
  # TimeZone.cc
  )                                                         ## 相当于: base_SRCS=Timestamp.cc

add_library(muduo_base ${base_SRCS})                        ## 将base_SRCS的文件生成为muduo_base的库文件
target_link_libraries(muduo_base pthread rt)                ## 需要链接pthread库和rt库

#add_library(muduo_base_cpp11 ${base_SRCS})
#target_link_libraries(muduo_base_cpp11 pthread rt)
#set_target_properties(muduo_base_cpp11 PROPERTIES COMPILE_FLAGS "-std=c++0x")

install(TARGETS muduo_base DESTINATION lib)
#install(TARGETS muduo_base_cpp11 DESTINATION lib)

file(GLOB HEADERS "*.h")
install(FILES ${HEADERS} DESTINATION include/muduo/base)

# if(MUDUO_BUILD_EXAMPLES)
#   add_subdirectory(tests)
# endif()

我们在mymuduo/muduo中执行./build.sh,编译成功后,就会在mymuduo文件夹下生成build目录,其内部存放我们编译成功生成的文件。编译成功,在mymuduo/build/release-cpp11/lib/目录下生成库文件libmuduo_base.a库文件。

编译:
muduo_base时间戳相关模块_第7张图片

编译后mymuduo/build目录结构:

muduo_base时间戳相关模块_第8张图片

接下来看Timestamp.h中对类Timestamp的定义,类图如下:

muduo_base时间戳相关模块_第9张图片

muduo_base时间戳相关模块_第10张图片

Timestamp.cc中,static_assert为编译时断言,我们平常使用的assert是运行时断言,在mymuduo/muduo/下创建tests目录,并在tests下创建sa.ccCMakeLists.txt,在tests下的CMakeLists.txt增加编译sa.cc的代码add_executable(sa sa.cc),在mymuduo/muduo/下的CMakeLists.txt中增加add_subdirectory(tests),表示把tests目录也加入编译,然后执行./build.sh编译代码,编译出的可执行程序sa会生成在mymuduo/build/release-cpp11/bin/目录下。

muduo_base时间戳相关模块_第11张图片

Timestamp.cc中实现的代码进行注释:

muduo_base时间戳相关模块_第12张图片

muduo_base时间戳相关模块_第13张图片

muduo_base时间戳相关模块_第14张图片

上述代码未对toString()toFormattedString()now()进行说明,这三个函数定义在Timestamp.cc中:

muduo_base时间戳相关模块_第15张图片

muduo_base时间戳相关模块_第16张图片

toString()是直接打印当前的秒和微秒,只不过上述代码中PRId64是一种跨平台的表达方式,如果是64位系统,等价于ld(long int),如果是64位系统,等价于lld(long long int)。其具体定义在C语言标准库头文件#include 中,使用时需包含该头文件。我们跳转至PRId64定义处查看:

muduo_base时间戳相关模块_第17张图片

接下来我们来看测试代码,在muduo/base/tests目录下,名为Timestamp_unittest.cc

muduo_base时间戳相关模块_第18张图片

我们在mymuduo/muduo/muduo/base/下创建tests,再将网络库muduo/base/tests/下的Timestamp_unittest.cc拷贝过去,并在mymuduo/.../base/下创建CMakeLists.txt,内容摘取网络库muduo/base/tests/CMakeLists.txt中的部分内容,内容如下:

add_executable(timestamp_unittest Timestamp_unittest.cc)
target_link_libraries(timestamp_unittest muduo_base)
add_test(NAME timestamp_unittest COMMAND timestamp_unittest)

然后回到mymuduo/muduo/下执行./build.sh进行编译,在mymuduo/build/release-cpp11/bin/生成可执行文件Timestamp_unittest

image.png
在运行该代码前,看下测试代码timestamp_unittest.cc实现:
muduo_base时间戳相关模块_第19张图片

muduo_base时间戳相关模块_第20张图片

运行测试代码,展示前面部分结果如下,对其进行部分注释:

1641193046.318001
1641193046.318001
1641193046.318001
1641193046.318073           // benchmark中第一次插入vector的时间戳
1641193046.344942           // benchmark中最后一次插入vector的时间戳
0.026869                    // 插入100万个时间戳花费的时间
 0: 977128
 1: 21464
 2: 1088
 3: 119
//... 省略打印信息

可以看到插入100万个时间戳,所花费的时间为0.02秒,通过timeDifference函数返回。

image.png

你可能感兴趣的:(后端c++)