spdlog在多執行緒中的使用

2021-08-22 17:59:00 字數 2900 閱讀 7669

開發需要,最近調研了幾個c++下的log庫,包括log4cpp、google glog、z-log、easylogger、spdlog等,鑑於spdlog的高效能且只包含標頭檔案,且執行緒安全,需要的特性基本都有了,最後決定,就它了!

spdlog是開源的,原始碼可訪問

spdlog可選擇向控制台、檔案、系統日誌以及控制器等目標輸出日誌,並可設定日誌輸出級別,以及定義日誌輸出格式等。

本人主要關注多執行緒向檔案的日誌輸出,所以其他幾個特性暫時先忽略。寫了個測試程式,測試兩個執行緒分別向同乙個log檔案輸出日誌。

spdlog的標頭檔案放在了環境變數/user/local/include中。由於實際使用中,存在跨檔案呼叫spdlog功能,因此我將其封成了乙個類。

#include #include #include #include "spdlog/spdlog.h" 

#include "spdlog/sinks/basic_file_sink.h"

#include "spdlog/logger.h"

#define log_path "./log/" //存在log的子目錄

#define use_log_file 1

using namespace std;

class my_log

string log_file_name; //log檔名

std::shared_ptrmy_logger; //建立的logger指標

bool log_file_created; //log檔案已建立標誌,以免有程序訪問了不存在的log file

bool logger_droped; //迴圈建立log檔案時使用,此測試程式中暫未使用

void create_log_file()

my_logger = spdlog::basic_logger_mt("basic_logger", log_full_path.str()); //建立basic_logger,注意該函式建立的是支援多執行緒的檔案輸出

spdlog::set_pattern("[%y-%m-%d %t][thread %t][%l]%v"); //設定logger的輸出格式

} void destroy_logger()

};

為了讓多個函式甚至多個檔案使用以上logger類,將其定義成了全域性變數:

my_log my_log;
簡單地寫兩個執行緒函式:

第乙個函式,首先建立名為mylog.log的log檔案,然後實現0~100數字的自相加操作,並將相加結果輸出到檔案my_log.log檔案中。

void *func_1(void *arg)

+ = ", i, i , i + i); //引數輸出的格式,使用{},{}中的0、1、2指示第幾個引數,:後的d指示以十進位制整數形式輸出

usleep(100000); }

return null;

}

第二個函式,實現0~100數字的自相乘計算,並將結果輸出到mylog.log中。由於與func_1使用同樣的log檔案,因此不需要再次建立logger,但需要首先判斷檔案是否存在,否則會出現程式崩潰。

void *func_2(void *arg)

for(int i = 0; i < 100; i++)

x = ", i, i , i * i);

usleep(100000); }

return null;

}

主函式,為以上兩個函式建立多執行緒:

int main()

編譯:

g++ -std=c++11 spdlog_test.cpp -o spdlog_test -lpthread

注意加上多執行緒庫pthread。

執行完成,下面是一段輸出檔案mylog.log截圖,可見兩個函式的輸出交替執行(**中為了防止函式執行速度過快導致看起來像是順序執行的現象,在每個函式中新增了usleep(100000),每執行完一步後,等待100ms)。

注意紅框中的格式,是我們在**中通過如下語句設定的:

spdlog::set_pattern("[%y-%m-%d %t][thread %t][%l]%v");
格式說明如下(來自網路

**中,我們log內容的輸出是通過如下info方式:

my_log.my_logger->info(" + = ", i, i , i + i);

在**中,可以根據訊息的級別,比如warning、error等,分別使用warn()和error()等方式,支援的級別如下:

typedef enum

level_enum;

如果,我們將測試**中的輸出級別分別設定成warning和error:

my_log.my_logger->warn(" +  = ", i, i , i + i);
my_log.my_logger->error(" x  = ", i, i , i * i);
輸出log就是這個樣子:

Synchronized在多執行緒中的使用

同步多執行緒 當兩個併發執行緒訪問同乙個物件object中的synchronized this 同步 塊時,一段時間內只能有乙個執行緒被執行,另乙個必須等待當前執行緒執行完這個 塊以後才能執行改 class task system.out.println nend task class thread...

MFC事件在多執行緒中的使用

handle mthreadeventdead mthreadeventdead createevent null,true,false,null 上面建立了乙個事件,createevent的具體使用如下。handle winapi createevent in opt lpsecurity att...

epoll在多執行緒下的使用

首先讓我們思考乙個問題,當乙個程序正在阻塞在epoll wait的時候,另乙個執行緒呼叫epoll ctl時會發生什麼呢,這個動作安全嗎?測試當epoll wait期間另乙個執行緒執行epoll ctl是否安全 其實這種動作是安全的 測試平台為linux,核心為4.4版本 先看一下man裡面的描述,...