具有STOP和继续信号的多线程,多处理

时间:2010-09-02 11:18:37

标签: java multithreading signals ptrace

我正在开发一个项目,我需要获得Java应用程序的本机堆栈。我能够部分实现这一目标。感谢ptrace / multiprocessing和信号。

在Linux上普通的java应用程序至少有14个线程。在这14个我感兴趣的只有主要线程,我必须得到本机堆栈。考虑到这个目标,我已经使用fork()启动了一个单独的进程,它监视主线程的本机堆栈。简而言之,我有两个独立的过程:一个是受监控的,另一个是使用ptrace和信号处理进行监控。

监控过程中的步骤:

1)从进程的其他14个线程中获取主线程id。

2)ptrace_attach main_ID

3)ptrace_cont main_ID

连续循环启动

{

4)kill(main_ID,SIGSTOP),

5)纳米睡眠并检查来自/ proc / [pid] / stat目录的状态

6)ptrace_peekdata读取堆栈并导航

7)ptrace_cont main_ID

8)纳米睡眠并检查来自/ proc / [pid] / stat目录的状态

}

9)ptrace_detach main_ID

这完美地提供了本机堆栈信息。但有时候我会面临一个问题。

问题:

当我向主线程发送kill(main_ID,SIGSTOP)时,来自进程的其他线程进入完成或停止状态(T)并且整个进程阻塞。这不是一致性行为,整个过程正确执行。我无法理解这种行为,因为我只是发信号主线程,为什么其他线程会受到影响呢? 有人可以帮助我分析问题吗?

我也尝试在进程的所有线程上执行CONT和STOP信号,但有时仍会出现问题。

谢谢,Sandeep

1 个答案:

答案 0 :(得分:0)

假设您使用的是Linux,那么您应该使用tkill(2)或tgkill(2)而不是kill(2)。在FreeBSD上,你应该使用SYS_thr_kill2系统调用。根据tkill(2)手册页:

  

tgkill()将信号sig发送到线程ID为tid的线程   线程组tgid。 (相比之下,kill(2)只能用于发送   作为整体的进程(即线程组)的信号和信号   将被传递到该过程中的任意线程。)

忽略关于tkill(2)的内容和朋友正在使用内部线程库,调试器/跟踪器通常使用它来向特定线程发送信号。

此外,你应该使用waitpid(2)(或它的一些变体)来等待线程接收SIGSTOP而不是轮询/ proc / [pid] / stat。这种方法将更有效,更具响应性。

最后,您似乎正在进行某种堆栈采样。您可能需要查看Google PerfTools,因为这些工具包括正在进行堆栈采样的CPU采样器,以获取消耗最多CPU时间的函数的估计值。您可以重用这些工具已经完成的工作,因为堆栈采样可能很难实现。