gpt4 book ai didi

C: select() - 信号中断

转载 作者:太空宇宙 更新时间:2023-11-04 01:45:33 25 4
gpt4 key购买 nike

我正在用 C 编写一个使用 AF_UNIX 套接字的多线程服务器程序。服务器的基本结构是:

  • 主线程初始化数据结构并创建一个“工作”线程池。
  • 工作线程开始在一个空的线程安全队列上等待新请求
  • 主线程通过 select() 调用监听各种套接字(新连接和已连接的客户端)。
    • select() 显示连接套接字上可能的读取:主线程调用 accept() 并将返回的文件描述符放入 fd_set (读集)。
    • select() 显示已连接套接字上的可能读取:主线程从 fd_set(读取集)中删除就绪文件描述符并将它们放入线程安全排队。
  • 工作线程从队列中提取文件描述符并开始与链接的客户端通信以服务于请求。在服务工作线程结束时,将套接字文件描述符放回 fd_set(我写了一个函数来使此操作线程安全),然后它再次返回队列等待新请求。

此例程无限循环重复,直到出现 SIGINT。必须在不退出循环的情况下对 SIGUSR1 执行另一个功能。

我对此表示怀疑,因为如果我发出 SIGINT,我的程序将以 EINTR = Interrupted system call 退出。我知道 pselect() 调用和“self pipe”技巧,但我不知道如何让它们在多线程情况下工作。

我正在寻找一个(POSIX 兼容的)信号管理来防止主线程等待 pselect() 时出现 EINTR 错误。

我发布了一些代码来澄清:

这里我设置了信号处理程序(忽略errorConsolePrint函数)

if(signal(SIGINT, &on_SIGINT) == SIG_ERR)
{
errorConsolePrint("File: %s; Line: %d; ", "Setting SIGINT handler", __FILE__, __LINE__);
exit(EXIT_FAILURE);
}
if(signal(SIGTERM, &on_SIGINT) == SIG_ERR)
{
errorConsolePrint("File: %s; Line: %d; ", "Setting SIGINT handler", __FILE__, __LINE__);
exit(EXIT_FAILURE);
}
if(signal(SIGUSR1, &on_SIGUSR1) == SIG_ERR)
{
errorConsolePrint("File: %s; Line: %d; ", "Setting to SIGUSR1 handler", __FILE__, __LINE__);
exit(EXIT_FAILURE);
}

if(signal(SIGPIPE, SIG_IGN) == SIG_ERR)
{
errorConsolePrint("File: %s; Line: %d; ", "Setting to ignore SIGPIPE", __FILE__, __LINE__);
exit(EXIT_FAILURE);
}

这里我为pselect设置了信号掩码

sigemptyset(&mask);
sigemptyset(&saveMask);
sigaddset(&mask, SIGINT);
sigaddset(&mask, SIGUSR1);
sigaddset(&mask, SIGPIPE);

这里我调用pselect

test = saveSet(masterSet, &backUpSet, &saveMaxFd);
CHECK_MINUS1(test, "Server: creating master set's backup ");

int test = pselect(saveMaxFd+1, &backUpSet, NULL, NULL, &waiting, &mask);
if(test == -1 && errno != EINTR)
{
...error handling...
continue;
}

希望得到一些帮助!提前谢谢大家。

最佳答案

您可能应该做的是将一个线程专用于信号处理。这是一个草图:

main 中,在生成任何线程之前,阻塞除 SIGILL、SIGABRT、SIGFPE、SIGSEGV 和 SIGBUS 之外的所有信号(使用 pthread_sigmask)。

然后,生成您的信号处理程序线程。此线程循环调用 sigwaitinfo 以获取您关心的信号。它采取适合每个人的任何行动;这可能包括向主线程发送一条消息以触发干净关闭(SIGINT),将“另一个函数”排队到工作池(SIGUSR1)中进行处理,等等。您安装处理程序对于这些信号。

然后你生成你的线程池,它根本不需要关心信号。

关于C: select() - 信号中断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54469854/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com