客户端 - 使用信号 SIGUSR1、SIGUSR2 传输文本的服务器程序
client - server program for transmitting text using signals 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, '[=10=]', sizeof(act_one));
memset(&act_zero, '[=10=]', 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: %d\n", 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, '[=11=]', 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);
}
截图显示工作、程序的结果。在第一种情况下,我多次致电客户。第二个有很多文字。显然,在这两种情况下,来自服务器的响应信号都不会消失。为什么?我不明白
enter image description here。
enter image description here
您在客户端程序中存在竞争条件。无法保证在客户端调用 pause
.
之后 发送信号
正确的方法是使用sigprocmask
和sigsuspend
。使用 sigprocmask
阻止传入 SIGUSR1
。发送位后,不调用 pause
,而是调用 sigsuspend
并使用解除阻塞 SIGUSR1
的掩码。 sigsuspend
会 return 当信号被捕获,并再次阻塞。
sigset_t myset, oldset;
sigemptyset(&myset);
sigaddset (&myset, SIGUSR1);
sigprocmask(SIG_BLOCK, &myset, &oldset);
while (*str)
{
...
// pause() -- wrong! race condition!
sigsuspend(&oldset);
...
}
服务器
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, '[=10=]', sizeof(act_one));
memset(&act_zero, '[=10=]', 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: %d\n", 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, '[=11=]', 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);
}
截图显示工作、程序的结果。在第一种情况下,我多次致电客户。第二个有很多文字。显然,在这两种情况下,来自服务器的响应信号都不会消失。为什么?我不明白 enter image description here。 enter image description here
您在客户端程序中存在竞争条件。无法保证在客户端调用 pause
.
正确的方法是使用sigprocmask
和sigsuspend
。使用 sigprocmask
阻止传入 SIGUSR1
。发送位后,不调用 pause
,而是调用 sigsuspend
并使用解除阻塞 SIGUSR1
的掩码。 sigsuspend
会 return 当信号被捕获,并再次阻塞。
sigset_t myset, oldset;
sigemptyset(&myset);
sigaddset (&myset, SIGUSR1);
sigprocmask(SIG_BLOCK, &myset, &oldset);
while (*str)
{
...
// pause() -- wrong! race condition!
sigsuspend(&oldset);
...
}