SIGCHLD waitpid, 在ndk开发简直就在踩屎坑

Posted bbqz007

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SIGCHLD waitpid, 在ndk开发简直就在踩屎坑相关的知识,希望对你有一定的参考价值。

原本项目中依赖子进程执行的地方,都使用jni调用java层的ProcessManager,换了c++ACE框架后,发现这些任务都很慢,调试才发现所有子进程执行的任务都必须等待到reactor超时才返回控制权。一时慌了居然怀疑是不是app进程没有收到SIGCHLD信号,所以调试跟踪了一下内核,信号正常。

既然收到了信号,那么去了哪里呢?

这里要说明一下ACE框架, ACE_Process_Manager会在handle_signal处理SIGCHLD信号,然后向reactor发一个notify,从而进入它的handle_input,在这里ACE_Process_Manager再通过waitpid查询出子进程号,从handler表中找出对应的handler,最后执行handler->handle_exit()。

SIGCHLD也就是子进程结束向父进程发的信号,并且在你进程某个队列挂入一个事件,这个事件可以通过waitpid系统调用查询WHOHANG,但这个事件在被waitpid就不存在了。一般的组合使用方式,在signal处理函数中调用waitpid取事件。而ACE框架的ACE_Process_Manager也是这样搭配使用,只不过waitpid延后到一个notify事件中进行。

 

好了回到本例,在这过程中,waitpid一直都返回0,表示没有这个事件,ACE框架必须依赖这个事件。这就奇怪了,有SIGCHLD信号却waitpid没有事件,(可参看一下https://stackoverflow.com/questions/43949142/will-wait-and-waitpid-block-sigchld-and-unblock-it-when-they-return-in-linux)。开始以为是android linux有问题,一直苦闷调试。最后当断点了waitpid后,一下子就明朗了,原来jni使用了java层的ProcessManager包,java虚拟机开了一个线程在wait4进而waitpid。

 

当子进程结束时,挂载到父进程也就是app进程的事件,先被art虚拟机用waitpid取出了。然后才到SIGCHLD信号处理,当ACE框架走到waitpid一步时,事件已经被art虚拟机偷走了,所以被耍了一转。

以上是关于SIGCHLD waitpid, 在ndk开发简直就在踩屎坑的主要内容,如果未能解决你的问题,请参考以下文章

Linux wait函数详解

linux第7天

linux wait 和waitpid

进程-

Android -- Init进程对信号的处理流程

[APUE]进程控制(中)