【发布时间】:2023-03-27 05:19:02
【问题描述】:
我正在编写一个多线程服务器应用程序,它会回显客户端发送的任何内容。我为每个新客户生成一个线程。我已经使用while(1) 循环无限期地处理连续的客户端(并非完全无限期,我已将其强制限制为 64,之后它拒绝任何新连接)。现在我需要在我的服务器应用程序中处理 Ctrl+C 信号。
一个问题是它的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);
}
}
我建议在 main() 中使用的取消线程的方法是:
// 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,线程最终将使用pthread_exit() 终止(满足要求1)。由于NOTES section of pthread_exit() 解释它允许其他线程继续执行(满足要求2)。
如果我一直到这里,
哪种方法最适合取消线程。
我选择了方法3,因为:
(缺点)方法 1:如果线程分配内存,异步线程取消是不安全的(正如我在 SO 中的答案中看到的那样),以及其他几个原因
(缺点)方法2:根据this link,还有很多其他函数也可以作为取消点,其中一些我将在我的代码中使用。
(优点)方法3:与方法2类似,但更安全,因为线程被取消禁用,其他取消点将不活动。
请告诉我我的方法是否正确?错了,除了使用 pthread_cancel() 之外,还有其他更好的方法来处理 Ctrl+C 吗?
【问题讨论】:
标签: c multithreading signals x86-64 suse