sth*_*sth 34
这将打印出a的十六进制表示pthread_t,无论实际是什么:
void fprintPt(FILE *f, pthread_t pt) {
unsigned char *ptc = (unsigned char*)(void*)(&pt);
fprintf(f, "0x");
for (size_t i=0; i<sizeof(pt); i++) {
fprintf(f, "%02x", (unsigned)(ptc[i]));
}
}
Run Code Online (Sandbox Code Playgroud)
只需打印一个小ID pthread_t就可以使用这样的东西(这次使用iostreams):
void printPt(std::ostream &strm, pthread_t pt) {
static int nextindex = 0;
static std::map<pthread_t, int> ids;
if (ids.find(pt) == ids.end()) {
ids[pt] = nextindex++;
}
strm << ids[pt];
}
Run Code Online (Sandbox Code Playgroud)
根据平台及其实际表示,pthread_t可能需要定义operator<for pthread_t,因为std::map需要对元素进行排序:
bool operator<(const pthread_t &left, const pthread_t &right) {
...
}
Run Code Online (Sandbox Code Playgroud)
Emp*_*ian 24
GDB在Linux上使用thread-id(又名内核pid,又名LWP)作为短数字.尝试:
#include <syscall.h>
...
printf("tid = %d\n", syscall(SYS_gettid));
Run Code Online (Sandbox Code Playgroud)
Jam*_*lis 16
在这种情况下,它取决于操作系统,因为POSIX标准不再需要pthread_t是算术类型:
应用IEEE Std 1003.1-2001/Cor 2-2004,项目XBD/TC2/D6/26,添加
pthread_t到不需要算术类型的类型列表中,从而允许pthread_t定义为结构.
您需要查看sys/types.h标题,看看如何pthread_t实现; 然后你可以打印出你认为合适的方式.由于没有可移植的方法来执行此操作,并且您没有说明您正在使用的操作系统,因此没有更多内容可以说.
编辑:为了回答您的新问题,每次新线程启动时,GDB都会分配自己的线程ID:
出于调试目的,gdb将自己的线程号 - 始终是一个整数 - 与程序中的每个线程相关联.
如果您正在考虑在每个线程内打印一个唯一的数字,那么最干净的选择可能是告诉每个线程启动它时使用的数字.
好的,这似乎是我的最终答案.我们有两个实际问题:
1.打印POSIX ID(pthread_t)
您可以简单地将pthread_t视为每个字节打印十六进制数字的字节数组.因此,您不受某些固定大小类型的限制.唯一的问题是字节顺序.您可能喜欢如果打印字节的顺序与打印的简单"int"相同.这是little-endian的示例,对于big-endian,只有订单应该被还原(在define?下):
#include <pthread.h>
#include <stdio.h>
void print_thread_id(pthread_t id)
{
size_t i;
for (i = sizeof(i); i; --i)
printf("%02x", *(((unsigned char*) &id) + i - 1));
}
int main()
{
pthread_t id = pthread_self();
printf("%08x\n", id);
print_thread_id(id);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
2.获取更短的可打印线程ID
在任何建议的情况下,您应该将实际线程ID(posix)转换为某个表的索引.但有两种截然不同的方法:
2.1.跟踪线程.
您可以跟踪表中所有现有线程的线程ID(它们的pthread_create()调用应该被包装)并且具有"重载"id函数,它只能获取表索引,而不是真正的线程ID.此方案对于任何内部线程相关的调试和资源跟踪也非常有用.显而易见的优点是线程级跟踪/调试工具的副作用,可能进一步扩展.缺点是需要跟踪任何线程创建/销毁.
这是部分伪代码示例:
pthread_create_wrapper(...)
{
id = pthread_create(...)
add_thread(id);
}
pthread_destruction_wrapper()
{
/* Main problem is it should be called.
pthread_cleanup_*() calls are possible solution. */
remove_thread(pthread_self());
}
unsigned thread_id(pthread_t known_pthread_id)
{
return seatch_thread_index(known_pthread_id);
}
/* user code */
printf("04x", thread_id(pthread_self()));
Run Code Online (Sandbox Code Playgroud)
2.2.只需注册新的线程ID.
在日志记录期间调用pthread_self()并搜索内部表,如果它知道线程.如果创建了具有此类ID的线程,则使用其索引(或从先前的线程重新使用,实际上并不重要,因为同一时刻没有2个相同的ID).如果尚未知道线程ID,则创建新条目以生成/使用新索引.
优点是简单.缺点是没有跟踪线程创建/销毁.因此,要跟踪这一点,需要一些外部机制.
| 归档时间: |
|
| 查看次数: |
95022 次 |
| 最近记录: |