perf_event_open()中的pid参数实际是否为tid?
求证:perf_event_open()中的pid参数实际是否为tid?
结论
perf_event_open()的第二个参数pid实际上对应的是线程ID(tid),而非传统意义上的进程ID(pid),这一点在多线程进程场景下会直观体现。
结合测试现象验证
你的测试结果完全符合这个结论:
监听单线程进程(pid=1)
执行代码:fd = perf_event_open(&attr, 1, -1, -1, 0);采样结果中
sample.pid == sample.tid,因为pid=1的进程(init/systemd)是单线程的,其进程ID和线程ID完全一致,所以两者数值相同。多线程进程(mysqld)测试
- 当用
fd = perf_event_open(&attr, -1, 0, -1, 0);监听CPU0的所有进程时,能正常捕获mysqld的采样数据,此时sample.pid是mysqld的进程ID,sample.tid是其内部工作线程的ID,符合预期。 - 但直接传入mysqld的进程ID作为
pid参数时(比如fd = perf_event_open(&attr, pidof(mysqld), 0, -1, 0);或fd = perf_event_open(&attr, pidof(mysqld), -1, -1, 0);),几乎得不到结果。原因是mysqld是多线程进程,你传入的进程ID其实是它主线程的tid,而主线程通常很少执行实际业务任务,大部分工作由子线程完成,自然采样不到数据。
- 当用
原理说明
在Linux系统中,进程和线程都属于内核的"任务(task)"实体,每个任务都有唯一的tid。传统的进程ID本质上是该进程主线程的tid,多线程进程的子线程会拥有独立的tid。perf_event_open的pid参数设计目标是指定单个任务(线程),所以如果要监听整个多线程进程的所有线程,不能直接传入进程ID,而是需要使用pid=-1配合其他参数,或者逐个指定每个线程的tid。
内容的提问来源于stack exchange,提问作者Yuchen Tang
相关产品推荐
相关产品推荐

