c-客户端-服务器程序,用于使用信号SIGUSR1、SIGUSR2传输文本



服务器

typedef struct s_server
{
unsigned char c;
int counter;
}               t_server;
t_server server;
void    ft_one(int sig, siginfo_t *info, void *context)
{
(void)sig;
(void)context;
server.c += server.counter;
server.counter /= 2;
if (server.counter == 0)
{
write(1, &server.c, 1);
server.c = 0;
server.counter = 128;
}
kill(info->si_pid, SIGUSR1);
}
void    ft_zero(int sig, siginfo_t *info, void *context)
{
(void)sig;
(void)context;
server.counter /= 2;
if (server.counter == 0)
{
write(1, &server.c, 1);
server.c = 0;
server.counter = 128;
}
kill(info->si_pid, SIGUSR1);
}
int main(void)
{
struct sigaction act_one;
struct sigaction act_zero;
memset(&act_one, '', sizeof(act_one));
memset(&act_zero, '', sizeof(act_zero));
act_one.__sigaction_u.__sa_sigaction = ft_one;
act_zero.__sigaction_u.__sa_sigaction = ft_zero;
act_one.sa_flags = SA_SIGINFO;
act_zero.sa_flags = SA_SIGINFO;
if (sigaction(SIGUSR1, &act_one, NULL) < 0)
return (0);
if (sigaction(SIGUSR2, &act_zero, NULL) < 0)
return (0);
printf("server pid: %dn", getpid());
server.c = 0;
server.counter = 128;
while (1)
pause();
return (0);
}

客户端

void empty(int sig, siginfo_t *info, void *context)
{
(void)sig;
(void)context;
(void)info;
}
int main(int argc, char **argv)
{
int i;
struct sigaction act;
char *str;
int serv_pid;
memset(&act, '', sizeof(act));
act.__sigaction_u.__sa_sigaction = empty;
act.sa_flags = SA_SIGINFO;
serv_pid = atoi(argv[1]);
str = argv[2];
if (sigaction(SIGUSR1, &act, NULL) < 0)
return (0);
while (*str)
{
i = 128;
while (i > 0)
{
if (i & (unsigned char)*str)
{
if (kill(serv_pid, SIGUSR1) == -1)
return (0);
}
else
{
if (kill(serv_pid, SIGUSR2) == -1)
return (0);
}
i /= 2;
pause();
}
str++;
}
return (0);
}

屏幕截图显示了工作的结果,程序。在第一种情况下,我给客户打了好几次电话。在第二个有很多文字。显然,在这两种情况下,来自服务器的响应信号都不会消失。为什么?我不能理解在此处输入图像描述。在此处输入图像描述

您在客户端程序中有一个竞赛条件。不能保证在客户端调用pause之后,信号将被传递

正确的方法是使用sigprocmasksigsuspend。用sigprocmask阻止传入的SIGUSR1。发送比特后,不调用pause,而是使用解锁SIGUSR1的掩码来调用sigsuspend。当信号被捕获时,sigsuspend将返回,并再次阻塞。

sigset_t myset, oldset;
sigemptyset(&myset);
sigaddset (&myset, SIGUSR1);
sigprocmask(SIG_BLOCK, &myset, &oldset);
while (*str)
{
...
// pause() -- wrong! race condition!
sigsuspend(&oldset);
...
}

最新更新