当我向服务器发送大量 kill() 命令时,我的服务器无法处理所有信号
my server doesn't handle all signals when I send it a lot of kill() commands
我对这段小代码有疑问。我有一个 "server" 和一个 "client"。服务器等待来自客户端的SIGUSR1
。但是当我循环发送 SIGUSR1
时,服务器不会处理每个信号!
我每次收到一个信号都会i++
,当我发送1000个信号时我得到981。
usleep()
和 sleep()
没有帮助。
这里是客户端代码:
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
int main(int ac, char **av)
{
int i = 0;
int status = 0;
if (ac < 2)
return (0);
printf("kill %s (%d)", av[1], atoi(av[1]));
for (i=0;i<=1000;i++)
{
printf("%d\n", i);
kill(atoi(av[1]), SIGUSR1);
}
kill(atoi(av[1]), SIGUSR2);
}
和服务器代码:
#include <signal.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int i = 0;
void sig2(int signum)
{
/* usleep(30); */
printf("%d\n", i);
i = 0;
}
void my_handler(int signum)
{
i++;
}
int main()
{
printf("pid: %d\n", getpid());
if (signal(SIGUSR1, my_handler) == SIG_ERR)
{
printf("rt\n");
exit(0);
}
signal(SIGUSR2, sig2);
while (1);
}
signal
的行为在平台之间不一致,在某些系统上信号是 one-shot,在其他系统上它是重复的。 Linux,具体来说,使用 System V 行为(除非定义了 _BSD_SOURCE
宏),即 one-shot。处理完信号后,它会重置为 SIG_DFL
.
要获得一致的行为,您应该使用 sigaction
而不是可以使用标志设置行为的地方。
您错过了一些信号,这些信号彼此 "on top" 到达,速度太快,应用程序无法处理。
If a subsequent occurrence of a pending signal is generated, it is implementation-defined as to whether the signal is delivered or accepted more than once in circumstances other than those in which queuing is required.
... 这是普通 UNIX 信号不需要排队的一种有点晦涩的说法。在大多数实现中,它们没有。例如,如果在处理之前产生了五个 SIGFOO 信号,则只有一个将被挂起,因此应用程序将只接收一个。
我对这段小代码有疑问。我有一个 "server" 和一个 "client"。服务器等待来自客户端的SIGUSR1
。但是当我循环发送 SIGUSR1
时,服务器不会处理每个信号!
我每次收到一个信号都会i++
,当我发送1000个信号时我得到981。
usleep()
和 sleep()
没有帮助。
这里是客户端代码:
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
int main(int ac, char **av)
{
int i = 0;
int status = 0;
if (ac < 2)
return (0);
printf("kill %s (%d)", av[1], atoi(av[1]));
for (i=0;i<=1000;i++)
{
printf("%d\n", i);
kill(atoi(av[1]), SIGUSR1);
}
kill(atoi(av[1]), SIGUSR2);
}
和服务器代码:
#include <signal.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int i = 0;
void sig2(int signum)
{
/* usleep(30); */
printf("%d\n", i);
i = 0;
}
void my_handler(int signum)
{
i++;
}
int main()
{
printf("pid: %d\n", getpid());
if (signal(SIGUSR1, my_handler) == SIG_ERR)
{
printf("rt\n");
exit(0);
}
signal(SIGUSR2, sig2);
while (1);
}
signal
的行为在平台之间不一致,在某些系统上信号是 one-shot,在其他系统上它是重复的。 Linux,具体来说,使用 System V 行为(除非定义了 _BSD_SOURCE
宏),即 one-shot。处理完信号后,它会重置为 SIG_DFL
.
要获得一致的行为,您应该使用 sigaction
而不是可以使用标志设置行为的地方。
您错过了一些信号,这些信号彼此 "on top" 到达,速度太快,应用程序无法处理。
If a subsequent occurrence of a pending signal is generated, it is implementation-defined as to whether the signal is delivered or accepted more than once in circumstances other than those in which queuing is required.
... 这是普通 UNIX 信号不需要排队的一种有点晦涩的说法。在大多数实现中,它们没有。例如,如果在处理之前产生了五个 SIGFOO 信号,则只有一个将被挂起,因此应用程序将只接收一个。