pthread_self() 贵吗?

Posted

技术标签:

【中文标题】pthread_self() 贵吗?【英文标题】:Is pthread_self() expensive? 【发布时间】:2014-03-03 21:15:48 【问题描述】:

pthread_self()ubuntu 12.04 贵吗? 它使用系统调用吗?

我想在每次线程写入日志时调用pthread_self(),这样我就会知道哪个线程写入日志并在日志中提及。所有线程都写入同一个日志文件。

【问题讨论】:

试试看吧。编写一个测试程序来调用它,比如 100,000 次并测量它的性能应该很容易。我猜它相当便宜,但我不确定。您可以使用strace 找出它产生的系统调用(如果有)。对于奖励积分,请回到这里并用您发现的内容发布您自己的问题的答案......我会支持它。 :) 不,它是 O(1),没有系统调用,而且非常便宜...从每个线程具有的特定结构中复制线程 id 作为已知偏移量,并使用一个应该始终保存的寄存器段。见unix.com/programming/… 【参考方案1】:

你可以在这里查看源代码:https://fossies.org/dox/glibc-2.19/pthread__self_8c_source.html

从上面的链接可以看到,pthread_self() 返回的 THREAD_SELF,定义为简单的汇编movl 指令。那里没有系统调用。当然,这是实现定义的。上面的链接指的是 glibc 库。

【讨论】:

【参考方案2】:

按照 dvnrrs 的建议,我写了以下code

#include <pthread.h>

int main(void) 

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

            pthread_self();
    
 

并使用time code 运行它

得到:

真正的 0m0.001s 用户 0m0.000s 系统 0m0.001s

运行循环 10000000 次给了我:

真正的 0m0.045s 用户 0m0.044s 系统 0m0.000s

我用strace -c -ttT ./code 运行它并得到了

% time seconds usecs/call 调用错误 syscall


-nan 0.000000 0 2 读取 -nan 0.000000 0 3 打开 -nan 0.000000 0 3 关闭 -nan 0.000000 0 3 fstat -nan 0.000000 0 11 映射 -nan 0.000000 0 5 mprotect -nan 0.000000 0 1 munmap -nan 0.000000 0 1 brk -nan 0.000000 0 2 rt_sigaction -nan 0.000000 0 1 rt_sigprocmask -nan 0.000000 0 1 1 访问 -nan 0.000000 0 1 执行 -nan 0.000000 0 1 getrlimit -nan 0.000000 0 1 arch_prctl -nan 0.000000 0 2 1 futex -nan 0.000000 0 1 set_tid_address -nan 0.000000 0 1 set_robust_list


100.00 0.000000 40 2 总计

【讨论】:

【参考方案3】:

即使pthread_self() 导致系统调用,它也将是一个相对便宜的系统调用,因为它只是查找结果。它绝对不会抓住任何锁(因为您需要的值是恒定的),或者做任何其他会消耗大量性能的事情。我预计会低于 1 微秒,但我可能错了。

如果在write() 调用之后立即调用它,则不必担心pthread_self() 的性能,因为write() 所需的时间会更长。毕竟,write() 确实需要获取锁以确保 POSIX 语义(即写入的数据立即对所有其他进程可见)。

如果您的实验表明 pthread_self() 确实执行了系统调用,您可以轻松地将其返回值缓存在您在 pthread 开始时设置的 thread_local 全局变量中(thread_local 关键字是如果我没记错的话,请参考 C/C++11 标准)。

【讨论】:

以上是关于pthread_self() 贵吗?的主要内容,如果未能解决你的问题,请参考以下文章

linux下多线程之pthread_detach(pthread_self())

pthread_self返回不同的值

线程的创建,pthread_create,pthread_self,pthread_once

pthread_self() 中的 Pthread id 与 dtrace 脚本中的数据不匹配

linux C语言 pthread_t pthread_self()函数(获取调用线程的ID) pthread_equal() 线程id(thread ID)

linux C语言 pthread_t pthread_self()函数(获取调用线程的ID) pthread_equal() 线程id(thread ID)