C++多线程调试宏

C++ Multithreaded debug macro

本文关键字:调试 多线程 C++      更新时间:2023-10-16

我正在尝试编写一个简单的调试宏,该宏将与运行它的多个线程一起工作。我显然缺少了一些东西,因为std::cout输出没有同步。非常感谢您的帮助。

//=======Debugger========//
#ifndef _DEBUGGER_H_
#define _DEBUGGER_H_
#include <iostream>
#include <thread>
#include <mutex>
/*
 * Debugger. All messages are directed to std::cout
 */
#ifndef WITH_NOCOLOR
 #define COLOR_GREEN        "e[0;32m"
 #define COLOR_RED          "e[1;91m"
 #define COLOR_CYAN         "e[1;36m"
 #define COLOR_YELLOW       "e[1;33m"
 #define COLOR_ORANGE       "e[0;33m"
 #define RESET_COLOR        "e[m"
#else
 #define COLOR_GREEN        ""
 #define COLOR_RED          ""
 #define COLOR_CYAN         ""
 #define COLOR_YELLOW       ""
 #define COLOR_ORANGE       ""
 #define RESET_COLOR        ""
#endif //WITH_NOCOLOR
#define THREAD_ID           "[thread: " << std::this_thread::get_id() << "] "
#define THREAD_SYNC_START   { std::lock_guard< std::mutex > lock( sync_mutex );
#define THREAD_SYNC_STOP    }
static std::mutex sync_mutex;
#define DEBUG       "[Debug]: "
#define ERROR       "[Error]: "
#define INFO        "[Info ]: "
#define WARNING     "[Warn ]: "
#define Debug(x)    do { THREAD_SYNC_START 
                    std::cout << COLOR_CYAN << DEBUG << RESET_COLOR <<  THREAD_ID << x << std::endl; 
                    THREAD_SYNC_STOP 
                    }while(0)
#define Err(x)      do { THREAD_SYNC_START 
                    std::cout << COLOR_RED << ERROR << COLOR_ORANGE << THREAD_ID << x << RESET_COLOR << std::endl; 
                    THREAD_SYNC_STOP 
                    }while(0)
#define Info(x)     do { THREAD_SYNC_START 
                    std::cout << INFO << THREAD_ID << x <<std::endl; 
                    THREAD_SYNC_STOP 
                    }while(0)
#define Warn(x)     do { THREAD_SYNC_START 
                    std::cout << COLOR_YELLOW << WARNING << RESET_COLOR << THREAD_ID << x << std::endl; 
                    THREAD_SYNC_STOP 
                    }while(0);
#endif //_DEBUGGER_H_

输出:

[Debug]:[线程:[调试]:[螺纹:1074275136]正在启动日志。。109953248]初始化启动

Youre sync_mutexstatic命名空间范围变量,这意味着它具有内部链接—包括报头的每个转换单元(.cpp文件)将具有其自己的互斥体副本。因此,来自不同翻译单元的访问是不同步的。

您需要确保整个程序只有一个sync_mutex对象。最明显的方法是将互斥对象转换为extern变量,而不是static变量,然后在一个源文件中定义它。

或者,如果您只想保留头,您可以将其作为内联函数中的静态局部变量:

#define THREAD_SYNC_START   { std::lock_guard< std::mutex > lock( sync_mutex() );
inline std::mutex& sync_mutex()
{
  static std::mutex m;
  return m;
}