【发布时间】:2019-11-04 05:58:26
【问题描述】:
当我 strace 这段代码时
void printMsg();
int main() {
signal(SIGPROF, printMsg);
struct itimerval tick;
memset(&tick, 0, sizeof(tick));
tick.it_value.tv_sec = 1; // sec
tick.it_value.tv_usec = 0; // micro sec.
tick.it_interval.tv_sec = 0;
tick.it_interval.tv_usec = 0;
setitimer(ITIMER_PROF, &tick, NULL);
while(1) {
;
}
return 0;
}
void printMsg() {
printf("%s","Hello World!!\n");
}
我在 1 秒后收到了SIGPROF 信号,如预期的那样
...
05:54:10 setitimer(ITIMER_PROF, {it_interval={0, 0}, it_value={1, 0}}, NULL) = 0
05:54:11 --- SIGPROF {si_signo=SIGPROF, si_code=SI_KERNEL} ---
...
但是当我在while(1) 中添加write(2, "", 0) 或read(2, "", 0) 之类的系统调用并再次strace 时,看起来SIGPROF 无法被触发。但是while(1)中的time(0)可以正常触发SIGPROF。
顺便说一句,我使用这段代码来模拟下面的 PHP 脚本,它忽略了 PHP-FPM SAPI 下的时间限制,
<?php
set_time_limit(5); // PHP uses setitimer(ITIMER_PROF) to implement this function
while (true) {
flush(); // PHP uses write(<fd>, "", 0) to implement this function
}
【问题讨论】:
-
如何得到输出格式?我的意思是你使用什么系统/编译器/工具。你能说吗?顺便说一句,我在
while循环中添加了write(1, STDIN_FILENO, 12);并捕获了信号。 -
请注意,您的信号处理函数
printMsg()是不安全的。您只能从信号处理程序中安全地调用异步信号安全函数。printf()不是异步信号安全的。在 Linux 上,请参阅 man7.org/linux/man-pages/man7/signal-safety.7.html -
@snr 是的,
write(1, STDIN_FILENO, 12);有效。我写了while (1) write(2, "", 0),又检查了一遍,这个空的write确实屏蔽了信号SIGPROF。我使用 gcc 版本 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.4)