我正在编写一个多线程服务器应用程序,它回应客户端发送的任何内容。我为每个新客户产生一个线程。我已经使用了一个while(1)
循环来无限期地处理连续的客户端(不完全不确定,我强制地将其限制为64,之后它拒绝任何新的连接)。现在我需要在我的服务器应用程序中处理Ctrl + C信号。从signal_handler例程中取消main()线程的正确方法是什么?
一个问题是它的not recommended在多线程应用程序中使用signal()
。
然而,即使我用它使用method already discussed at SO这是我需要做的,赶上SIGINT
信号(从按Ctrl + C):
1)服务器不应该再接受更多的客户。
2)当前连接到服务器应该继续,除非客户端选择断开连接。
我的信号处理函数是:
void Ctrl_C_handler(int sig)
{
if(sig == SIGINT) // Ctrl+C
{
printf("Ctrl+C detected by server !!\n");
printf("No more connections will be accepted!!");
pthread_cancel(main_thread_id);
}
}
的方法我建议里面主要使用()取消线程是:
// Method 1
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
while(1)
{
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
// ..
// client handling
// ..
}
// Method 2
while(1)
{
pthread_testcancel(); // Create Cancellation point
// ..
// client handling
// ..
}
// Method 3
while(1)
{
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
pthread_testcancel();
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
// ..
// client handling
// ..
}
原因为什么我使用pthread_cancel()
:
根据this link th e线程将最终使用pthread_exit()
(满足要求1)终止。由于NOTES section of pthread_exit()
解释说它允许其他线程继续执行(要求2完成)。
现在,如果我是正确的,直到在这里,
哪种方法是最好的线程的取消。
我选择的方法3,因为:
(记过)方法1:异步线程取消并不安全(因为我在SO答案看见)如果线程分配内存,以及其他一些原因
(记过)方法2:根据this link,有很多其他功能也可以作为取消点,我将在我的代码中使用一些功能。方法3:与方法2类似,但更安全,因为其他取消点将不会被激活,因为线程被取消禁用。
请告诉我,我的方式是否正确?它的错误,除了使用pthread_cancel()之外,还有其他更好的方法来处理Ctrl + C吗?
我在想,pthread_cancel()不应该在正常情况下使用,但无法拿出更优雅的东西(正如您的方法),感谢解决方案。 –
我还发现了一个[类似的代码](http://www.cs.cf.ac.uk/Dave/C/node32.html#SECTION003240000000000000000)。此代码使用完全不同的线程进行信号处理。 –
**一个简单的问题**我在使用此方法时注意到:当调用accept()时,它可能会复制listen_fd的值,并使用它接受客户端。因此,即使'listen_fd'由signal_handler关闭,而主线程被阻塞(通过'accept()'),'accept()'调用可能会成功返回,因此具有正确的'client_fd'。解决方案:在accept()后也检查'listen_fd'的有效性。 –