【发布时间】:2019-06-25 11:04:23
【问题描述】:
我正在用 C 语言编写一个与 AF_UNIX 套接字一起工作的多线程服务器程序。 服务器的基本结构是:
- 主线程初始化数据结构并创建一个“工作”线程池。
- 工作线程开始等待空线程安全队列上的新请求
- 主线程使用
select()调用监听各种套接字(新连接和已连接的客户端)。-
select()揭示了连接套接字上可能的读取:主线程调用accept()并将返回的文件描述符放入fd_set(读取集)。 -
select()揭示了已连接套接字上可能的读取:主线程从fd_set(读取集)中删除准备好的文件描述符并将它们放入线程安全队列中。
-
- 工作线程从队列中提取文件描述符并开始与链接客户端通信以服务请求。在服务工作线程结束时,将套接字文件描述符放回
fd_set(我编写了一个函数来使此操作线程安全),然后它返回在队列中再次等待新请求。
此例程在无限循环中重复,直到引发 SIGINT。 必须在不退出循环的情况下对 SIGUSR1 执行另一个功能。
我对此表示怀疑,因为如果我使用EINTR = Interrupted system call 提出 SIGINT 我的程序退出。
我知道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;
}
希望能得到一些帮助! 提前谢谢大家。
【问题讨论】:
-
我不太了解您真正想知道的内容。如何对
SIGINT和SIGUSR1的情况进行不同的处理?如何终止多线程进程?如何优雅地 终止多线程进程?还有什么? -
EINTR 错误发生在你程序的什么地方?
-
我的问题是:如何配置信号管理以防止在进程等待
select()调用时出现错误“系统调用中断” -
基本计划存在严重缺陷。强烈建议:在
main()设置线程池,设置信号处理程序,调用socket(),调用任意setsockopt()s,调用bind()调用listen()然后,在循环中调用accept()然后通过socket从accept()返回到可用线程。然后线程处理与客户端的所有通信,包括最终关闭套接字 -
@user3629249 为什么你认为这个结构有缺陷?您建议的那个不合时宜,因为客户端(即给定,我无法修改它)可以在两个请求之间等待很长时间,这样一个线程可以无限期地被占用。
标签: c sockets signals multiplexing