30 day self-made C + + server day13-C + + engineering and performance optimization

Posted by hukadeeze on Tue, 04 Jan 2022 20:56:27 +0100

In the previous tutorial, we have completely developed the core architecture of a master-slave Reactor multithreaded server. The next development focus should shift from architecture to details. Before that, it is necessary and necessary to modernize and engineer the whole project.

The first step in C + + project engineering must be to use CMake. At present, all files are placed in one folder and are not classified. With more and more complex projects and more modules, developers need to consider the readability of this Shishan, such as splitting modules into different folders and putting header files together. For such a complex project, if you hand write a complex Makefile to compile links, it will be quite responsible and cumbersome. We should use CMake to manage our project. The use of CMake is very simple and powerful. It will help us automatically generate Makefile files, make it easier to compile and link the project, and programmers can focus more on writing code.

The compilation and linking of C + + seems simple, but it is actually quite cumbersome and complex. For the specific principle, please refer to Chapter 7 of in-depth understanding of computer system (Third Edition). If you don't have CMake, you will spend half of your time compiling links in developing a large c + + project.

We put the core library in the src directory, the test program using the network library in the test directory, and all header files in the / include directory:

set(PINE_SRC_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/src/include)
set(PINE_TEST_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/test/include)
include_directories(${PINE_SRC_INCLUDE_DIR} ${PINE_TEST_INCLUDE_DIR})

Implement the of header file cpp files are placed in the src directory according to modules (modules have not been split into different folders in this version).

src directory is a network library. There is no executable program. We only need to add the name of this network library cpp files are compiled and linked into multiple target files, and then linked to a shared library:

file(GLOB_RECURSE pine_sources ${PROJECT_SOURCE_DIR}/src/*.cpp)
add_library(pine_shared SHARED ${pine_sources})

During compilation, it is also convenient to set compilation parameters according to different environments:

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -Wall -Wextra -std=c++17 -pthread")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-parameter -Wno-attributes") #TODO: remove
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 -ggdb -fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls")
set(CMAKE_EXE_LINKER_FLAGS  "${CMAKE_EXE_LINKER_FLAGS} -fPIC")

Use the in the test directory cpp file code for creating executable file:

foreach (pine_test_source ${PINE_TEST_SOURCES})
    get_filename_component(pine_test_filename ${pine_test_source} NAME)
    string(REPLACE ".cpp" "" pine_test_name ${pine_test_filename})

    add_executable(${pine_test_name} EXCLUDE_FROM_ALL ${pine_test_source})
    add_dependencies(build-tests ${pine_test_name})
    add_dependencies(check-tests ${pine_test_name})

    target_link_libraries(${pine_test_name} pine_shared)

    set_target_properties(${pine_test_name}
        PROPERTIES
        RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
        COMMAND ${pine_test_name}
    )
endforeach(pine_test_source ${PINE_TEST_SOURCES})

Notice that we switched to the more powerful and useful clang compiler (formerly GCC).

After configuring CMake and clang, you need to do the following three things:

  1. format: as a large c + + project, it may be developed by many programmers. Everyone's coding habits and styles are different. The whole project may have messy styles and poor readability, which is not conducive to project maintenance. Therefore, when writing C + + code, we should abide by some conventions to unify the style of the code. At present, the popular C + + code styles include google, llvm, etc. the project adopts google style.
  2. Cpprint: a static code analysis tool based on google C + + coding specification, which can find errors, violations of conventions and suggestions for modification in the code.
  3. Clang tidy: the code analysis tool of clang compiler is very powerful. You can not only find various static errors in the code, but also prompt problems that may occur at run time. In addition, we can also give some suggestions to improve the program performance through code analysis.

These three things can ensure that we write projects with consistent style, fewer bug s, good performance and compliance with google coding specifications. They are necessary tools for developing large-scale C + + projects.

In order to automatically run with one click, these three tools have been saved in build in the form of python script_ Support directory:

build_support
    - clang_format_exclusions.txt     // No formatted code is required
    - run_clang_format.py             // format
    - cpplint.py                      // cpplint
    - run_clang_tidy_extra.py         // Help files, do not run directly
    - run_clang_tidy.py               // clang-tidy
.clang-format                         // format configuration
.clang-tidy                           // Clang tidy configuration

format is in cmakelists Txt:

# runs clang format and updates files in place.
add_custom_target(format ${PINE_BUILD_SUPPORT_DIR}/run_clang_format.py
        ${CLANG_FORMAT_BIN}
        ${PINE_BUILD_SUPPORT_DIR}/clang_format_exclusions.txt
        --source_dirs
        ${PINE_FORMAT_DIRS}
        --fix
        --quiet
        )

cpplint is in cmakelists Txt:

add_custom_target(cpplint echo '${PINE_LINT_FILES}' | xargs -n12 -P8
        ${CPPLINT_BIN}
        --verbose=2 --quiet
        --linelength=120
        --filter=-legal/copyright,-build/include_subdir,-readability/casting
        )

Clang tidy at cmakelists Txt:

add_custom_target(clang-tidy
        ${PINE_BUILD_SUPPORT_DIR}/run_clang_tidy.py # run LLVM's clang-tidy script
        -clang-tidy-binary ${CLANG_TIDY_BIN}        # using our clang-tidy binary
        -p ${CMAKE_BINARY_DIR}                      # using cmake's generated compile commands
        )

A lot of information such as folder definition is omitted here and is completely configured in the source code.

Next, try to compile our project. First, create a build folder to prevent files from mixing with the project:

mkdir build
cd build

Then use CMake to generate a Makefile:

cmake ..

After generating the Makefile, use the following command to format the code:

make format

Then check the code with cpprint:

make cpplint

Finally, use clang tidy for code analysis:

make clang-tidy

Modify all warnings and rerun these three commands until they all pass. Then use the make command to compile the entire network library, which will be saved to the lib folder, but there is no executable file here. If we need to compile the executable server, we need to compile the corresponding source files under the test directory:

make server
make multiple_client
make single_client

The generated executable file is in the build/test directory, which is used at this time/ test/server to run the server.

So far, today's tutorial is over. Today, we have engineered the whole project, using CMake, format, cpplint and clang tidy. The code style has changed to Google style, fixed many bugs in previous versions, applied the modern C + + project suggestions provided by these tools, and the performance has been improved. In today's version, all classes are also made incopy and immovable. The parameter passing by value prompted by clang tidy has also been modified to reference parameter passing, which reduces a large number of copy operations. The modifications suggested by these tools have greatly reduced the probability of bugs and improved the server performance. Although no performance testing tools have been used, the processing speed, throughput and concurrency support of the server have been significantly improved.

Complete source code: https://github.com/yuesong-feng/30dayMakeCppServer/tree/main/code/day13

Topics: C++ Linux server Optimize