某些信号没有被SIGC捕获

我正在尝试编写一个程序,使用服务器和客户端两个进程模拟服务器和客户端之间的通信:

我们将首先启动服务器,然后启动客户端(使用参数/client[server PID][Message]),我可以只使用UNIX信号向服务器发送字符串消息,因此我使用两个信号SIGUSR1SIGUSR2以二进制形式发送字符值,然后在服务器中将其转换回char并显示:下面是我的客户机代码:

\include<minitalk_client.h>
void将消息发送到服务器(pid\u t ppid,const unsigned char*msg)
{
无符号字符掩码;
int i;
ft_putstr(“发送消息”);
ft_putstr((const char*)msg);
ft_putstr(“to server:”);
ft_putnbr(ppid);
ft_putchar('\n');
while(*msg)
{
遮罩=1<<7;
while(面具)
{
如果(*消息和掩码)
kill(ppid,SIGUSR1);
其他的
kill(ppid,SIGUSR2);
usleep(300);
面罩>>=1;
}
msg++;
}
i=-1;
而(++i<8)
{
kill(ppid,SIGUSR2);
usleep(300);
}
}
int main(int argc,字符**argv)
{
int-ppid;
如果(argc!=3)
{
写入(2,“无效参数”\n“18);
申报表(1);
}
ppid=ft_原子(argv[1]);
将消息发送到服务器(ppid,(const unsigned char*)argv[2]);
返回(0);
}

和服务器:

\include<minitalk_server.h>
无效信号处理器(int sig)
{
静态无符号字符;
静态无符号字符掩码=1<<7;
静态布尔值为新消息=true;
如果(是新消息)
{
ft_putstr(“收到来自客户的消息:”);
is_new_message=false;
}
if(sig==SIGUSR1)
字符|=掩码;
面罩>>=1;
如果(!掩码)
{
如果(字符)
ft_putchar(字符);
其他的
{
ft_putchar('\n');
is_new_message=true;
}
字符=0;
遮罩=1<<7;
}
}
内部主(空)
{
结构动作法;
常数pid_t pid=getpid();
sigemptyset(和act.sa_面具);
act.sa_handler=sig_handler;
sigaction(SIGUSR1和act,0);
sigaction(SIGUSR2和act,0);
ft_putstr(“启动了带pid的minitalk服务器”);
ft_putnbr(pid);
ft_putchar('\n');
而(1)
暂停();
返回(0);
}

因此,我的代码可以正常工作,但我在睡眠方面有一个问题,当我没有等待足够的时间时,某些信号不会被捕获,它会执行以下操作:

连续暂停会议�@������\@����@����@��������@�����\@��������@������@����@��@���������@������\@�����@���@������@���������十、

我不想等太久,因为这会使我的程序太慢,所以有没有办法把信号输入到;“排队”;所以当我想在一个循环中发送多个信号时,不需要在每个信号之间等待

(我知道信号不是最好的方法,但这是一个学校项目,我只被允许这么做)

我不想等太久,因为这会让我的程序太慢

,这样问是有道理的

有没有办法把信号放在;“排队”;所以当我想在一个循环中发送多个信号时,不需要在每个信号之间等待

。但实际上没有,SIGUSR1SIGUSR2,其他普通信号不排队。因此,不仅每次最多只能有一个挂起,而且如果同时有SIGUSR1SIGUSR2挂起,那么它们的交付顺序是未指定的,并且可能与客户提出它们的顺序不同

但可能还有另一种方法可以加速交互并使其更加可靠,同时仍然只依赖信号进行通信。通过在注册处理程序时设置SA_SIGINFO标志,可以使用接受三个参数的处理程序,第二个参数是指向SIGINFO_t的指针,该结构包含有关信号的信息。该信息包括发送该信息的进程的PID。您可以使用它使服务器通过向客户端发送信号来确认收到每个信号。然后,客户端将在发送下一个信号之前等待每个信号的确认

服务器将执行以下操作:

void sig\u处理程序(int sig,siginfo\u t*info,void*ignore){
// ...
杀死(信息->si_pid,SIGUSR1);
}
内部主(空){
struct sigaction act={.sa_sigaction=sig_handler,.flags=sa_SIGINFO};
sigemptyset(和act.sa_面具);
sigaction(SIGUSR1和act,0);
sigaction(SIGUSR2和act,0);
// ...
}

如果您想执行此操作,那么我将客户端修改留给您,但我建议您考虑这一方(至少)通过“代码”> SIGWAITE()/代码>同步地接收信号,而不是通过信号处理程序异步接收。

发表评论