我试图找出一种通过其子进程在 C 进程中进行分析的方法,过了一会儿,父进程会终止其子进程以停止分析。我正在使用性能来分析我的应用程序。 perf将在杀死时将其结果输出到文件中。在bash脚本中看起来像这样:
./run &
perf stat -o perf.data -p <pid_run> &
kill -9 <pid_perf>
到目前为止我做了什么:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
static pid_t perf_id;
void start() {
char *filename="test_data";
char ppid_str[24];
pid_t pid = fork();
if (pid == 0){
pid_t ppid = getppid();
sprintf(ppid_str, "%d",ppid);
char *args[] = {"/usr/bin/perf", "stat","-p",ppid_str,"-o", filename, NULL};
execvp(args[0], args);
}
else {
perf_id = pid
}
}
void stop() {
kill(perf_id,SIGKILL);
}
我在获取性能的输出时遇到问题。 这是可以运行父进程的代码示例:
int main() {
start();
int a = 0;
a+=1;
stop();
// ... // There are other instructions after the stop
return 0;
}
运行此代码时,我没有从perf获得任何输出。我必须杀死父进程才能获得输出。
如果我在杀死子进程之前进行了一次sleep调用,那么程序将输出一个空文件。
编辑:
stat 参数是我命令中的一个示例,我还想使用记录参数
正如Zulan所提到的,如果我使用SIGINT
而不是SIGKILL
,我将得到一个输出,但只有当主进程休眠1秒时我才能获得一个输出。
答案 0 :(得分:1)
您应该发送SIGINT
而不是SIGKILL
,以便允许perf
干净地关闭并生成有效的输出文件。 perf
子进程和主进程之间的同步仍然不完善 - 因此如果主进程没有像您的示例那样花费大量时间,则很可能根本不会生成任何输出文件。这也会影响收集数据的准确性。设置使用perf
作为子进程而不是反之亦然,您无法真正改进它。
答案 1 :(得分:0)
问题是perf将自身附加到进程,然后等待进程终止以打印计数器。尝试添加例如
-I msec
选项,像-I 1000一样每隔1秒打印一次计数器。 将你的args更改为execvp
char *args[] = {"/usr/bin/perf", "stat", "-p",ppid_str,"-o", filename, "-I", "1000", NULL};
并将你的公司转为类似
的循环while (a < 10) {
a += 1;
sleep(1);
}
虽然在这种方法中文件没有正确关闭(),但是会产生结果。 我会创建一个小的二进制文件,执行perf超时并正常关闭文件并从子进程运行。