dro*_*rox 16 c multithreading variadic-functions
在一个多线程程序中,我正在编写一个自定义打印函数,它接受一个可变参数列表.
void t_printf(char * str, ...)
{
if(file_ptr != NULL)
{
va_list ap;
va_start(ap, str);
vfprintf(file_ptr, str, ap);
va_end(ap);
fflush(file_ptr);
}
}
Run Code Online (Sandbox Code Playgroud)
在这个函数里面,我想将当前线程id(使用pthread_self()
)添加到要打印的消息中.我该怎么做?有没有办法将其添加到现有的va_list?
Arn*_*anc 21
使用可变参数宏,您可以使用前置或附加的参数调用该函数:
#define t_printf(format, args...) \
_t_printf(format, thread_id, __VA_ARGS__);
Run Code Online (Sandbox Code Playgroud)
这预先thread_id
在其他论点之前.(注意,在_t_printf()
函数上你也必须修改格式字符串.)
如果你这样做:
t_printf("some format string", a, b, c);
Run Code Online (Sandbox Code Playgroud)
这将扩展这样做:
_t_printf("some format string", thread_id, a, b, c);
Run Code Online (Sandbox Code Playgroud)
如果t_printf()
在没有格式化的其他参数的情况下调用,则会有一个尾随逗号.GCC有一个##
扩展,负责根据需要添加逗号:
#define t_printf(format, args...) \
_t_printf(format, thread_id ##__VA_ARGS__);
Run Code Online (Sandbox Code Playgroud)
完整的宏解决方案:
#define t_printf(format, args...) \
_t_printf(format, thread_id, __VA_ARGS__);
void _t_printf(char * str, ...)
{
if(file_ptr != NULL)
{
char format[1024];
/* safely prefix the format string with [thread_id: %x] */
snprintf(format, sizeof(format), "%s%s", "[thread_id: %x] ", str);
va_list ap;
va_start(ap, str);
vfprintf(file_ptr, format, ap);
va_end(ap);
fflush(file_ptr);
}
}
Run Code Online (Sandbox Code Playgroud)
另一个解决方案是做两个printf()s:
vsnprintf(buffer, bufsize, str, ap);
vfprintf(file_ptr, "[thread_id: %x] %s", thread_id, buffer);
Run Code Online (Sandbox Code Playgroud)
完整解决方案
void _t_printf(char * str, ...)
{
if(file_ptr != NULL)
{
char buffer[1024];
va_list ap;
va_start(ap, str);
vsnprintf(buffer, sizeof(buffer), str, ap);
vfprintf(file_ptr, "[thread_id: %x] %s", thread_id, buffer);
va_end(ap);
fflush(file_ptr);
}
}
Run Code Online (Sandbox Code Playgroud)
我相信没有标准的方法来操纵va_list.stdarg.h头定义了用于声明,初始化,复制,终止列表和获取参数的宏(识别类型取决于调用者).
以下是完成相同结果的替代方案的建议:请注意,这会对字符串的格式施加限制.根据您的需要,它可能不是问题:
#define MAXLEN 256
void t_printf(char * str, ...)
{
if(file_ptr != NULL)
{
va_list ap;
va_start(ap, str);
char msg[MAXLEN];
vsnprintf( msg , MAXLEN , str , ap ); /* msg is guaranteed
* to be NULL terminated
*/
/* Now that we have the message printed into a string,
* print the message, along with the thread_id into the
* console
*/
fprintf( file_ptr, "thread % 6d: %s", pthread_self() , msg );
va_end(ap);
fflush(file_ptr);
}
}
Run Code Online (Sandbox Code Playgroud)