客户端 - 使用信号 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.

之后 发送信号

正确的方法是使用sigprocmasksigsuspend。使用 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);
  ...
}