有没有获取线程号的C API?日志怎么打印线程号? HarmonyOS 鸿蒙Next

有没有获取线程号的C API?日志怎么打印线程号? HarmonyOS 鸿蒙Next 使用 OH_LOG_SetCallback 设置日志回调,实现保存日志到文件的功能,

这个进程中有多个线程,怎么在日志中增加线程号?回调的内容中没有线程号


更多关于有没有获取线程号的C API?日志怎么打印线程号? HarmonyOS 鸿蒙Next的实战教程也可以访问 https://www.itying.com/category-93-b0.html

2 回复

以下内容仅供参考

在鸿蒙系统中通过C++实现带线程号的日志回调,需要注意线程安全和线程ID获取。以下是实现方案:

#include <mutex>
#include <fstream>
#include <thread>
#include <chrono>
#include <iomanip>
#include "hilog/log.h"

std::mutex g_logMutex;
std::ofstream g_logFile("app.log", std::ios::app);

void LogCallback(OH_LogLevel level, const char* tag, const char* fmt, ...) {
    std::lock_guard<std::mutex> lock(g_logMutex);
    
    // 获取线程ID
    std::stringstream threadIdStream;
    threadIdStream << std::this_thread::get_id();
    std::string threadId = threadIdStream.str();

    // 获取时间戳
    auto now = std::chrono::system_clock::now();
    auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
        now.time_since_epoch()) % 1000;
    auto timer = std::chrono::system_clock::to_time_t(now);
    std::tm bt = *std::localtime(&timer);
    
    // 格式化日志
    char timestamp[24];
    snprintf(timestamp, sizeof(timestamp), 
        "%04d-%02d-%02d %02d:%02d:%02d.%03ld",
        bt.tm_year + 1900, bt.tm_mon + 1, bt.tm_mday,
        bt.tm_hour, bt.tm_min, bt.tm_sec, ms.count());

    // 解析可变参数
    va_list args;
    va_start(args, fmt);
    char logContent[1024];
    vsnprintf(logContent, sizeof(logContent), fmt, args);
    va_end(args);

    // 组合完整日志行
    std::string levelStr;
    switch(level) {
        case LOG_DEBUG: levelStr = "D"; break;
        case LOG_INFO:  levelStr = "I"; break;
        case LOG_WARN:  levelStr = "W"; break;
        case LOG_ERROR: levelStr = "E"; break;
        default:        levelStr = "U";
    }
    
    std::stringstream logLine;
    logLine << timestamp 
            << " [" << threadId << "] "
            << levelStr << "/" << tag << ": " 
            << logContent << std::endl;

    // 写入文件
    if (g_logFile.is_open()) {
        g_logFile << logLine.str();
        g_logFile.flush();
    }
}

// 初始化函数
void InitLogSystem() {
    OH_LOG_SetLogLevel(LOG_LEVEL_DEBUG);
    OH_LOG_SetCallback(LogCallback);
}

关键实现要点:

  • 线程安全机制

    • 使用std::mutex保证文件写入的原子性
    • 通过std::lock_guard实现RAII风格的锁管理
    • 每次回调都进行完整的日志组装和写入操作
  • 线程ID获取

    std::stringstream threadIdStream;
    threadIdStream << std::this_thread::get_id();
    

    使用C++标准库获取当前线程ID,输出示例:140245072824064

  • 高性能时间戳

    • 使用<chrono>获取毫秒级精度时间
    • 通过std::localtime转换本地时间
    • 格式示例:2024-03-20 14:35:22.358
  • 日志格式优化

    2024-03-20 14:35:22.358 [140245072824064] D/MyTag: debug message
    

    包含:

    • 时间戳(精确到毫秒)
    • 线程ID(方括号包裹)
    • 日志级别(单字母表示)
    • 日志标签
    • 原始日志内容
  • 文件操作优化

    • 使用std::ios::app保证日志追加模式
    • 每次写入后执行flush保证数据持久化
    • 检查文件打开状态避免崩溃

更多关于有没有获取线程号的C API?日志怎么打印线程号? HarmonyOS 鸿蒙Next的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS(鸿蒙Next)中,获取线程号可以使用pthread_self()函数,该函数返回当前线程的线程ID。线程ID的类型为pthread_t

要在日志中打印线程号,可以使用printfhilog函数。以下是一个示例:

#include <pthread.h>
#include <stdio.h>
#include <hilog/log.h>

void* thread_function(void* arg) {
    pthread_t tid = pthread_self();
    printf("Thread ID: %lu\n", (unsigned long)tid);
    HILOG_INFO(LOG_APP, "Thread ID: %lu\n", (unsigned long)tid);
    return NULL;
}

int main() {
    pthread_t thread;
    pthread_create(&thread, NULL, thread_function, NULL);
    pthread_join(thread, NULL);
    return 0;
}

在这个示例中,pthread_self()用于获取当前线程的ID,printfHILOG_INFO分别用于在控制台和系统日志中打印线程ID。

回到顶部