gpt4 book ai didi

c - 捕获SIGINT信号后退出程序

转载 作者:行者123 更新时间:2023-11-30 16:47:30 26 4
gpt4 key购买 nike

我有一个使用 OpenMP 实现的客户端应用程序。该程序在收到 SIGINT 信号时终止,但在这种情况下,它应该首先向服务器发送一条消息,指示用户已注销。我已经成功实现了消息传递,但我无法让程序随后终止。

这是我的代码的并行部分:

#pragma omp parallel num_threads(4)
{
#pragma omp sections
{
#pragma omp section
{
while(1)
{
char pom[1000];
fgets(pom, 1000, stdin);
if (strlen(pom) != 1)
{
char * buffer;
buffer = message(username, pom);
if (send(client_socket, buffer, strlen(buffer), 0) < 0)
{
callError("ERROR: cannot send socked");
}
bzero(pom, 1000);
free(buffer);
}
}
}
#pragma omp section
{
char buffer[4096];
char * data;
ssize_t length;
int received = 0;
int data_cap = 4096;
while(1)
{
data = calloc(BUFFER_LEN, sizeof(char));
while ((length = read(client_socket, buffer, BUFFER_LEN)) > 0)
{
received += length;
if (received > data_cap)
{
data = realloc(data, sizeof(char) * data_cap * 2);
data_cap = data_cap * 2;
}
strcat(data, buffer);
if (!isEnough(data))
{
break;
}
}
printf("%s", data);
free(data);
bzero(buffer, BUFFER_LEN);
data_cap = 4096;
received = 0;
length = 0;
}
}
#pragma omp section
{
void sig_handler(int signo)
{
char * welcome1 = calloc(strlen(username) + 13, sizeof(char));
strcat(welcome1, username);
strcat(welcome1, " logged out\r\n");
if (send(client_socket, welcome1, strlen(welcome1), 0) < 0)
{
callError("ERROR: cannot send socked");
}
free(welcome1);
}

while (1)
{
if (signal(SIGINT, sig_handler) == SIG_ERR)
printf("\ncan't catch SIGINT\n");
while (1)
sleep(1);
}
}
}

如何让程序在捕获信号后终止?

最佳答案

您的程序有几个严重的问题。

首先,您尝试将信号处理函数定义为嵌套函数。 C 没有嵌套函数。您的代码能够编译必然意味着您依赖于语言扩展,并且将其与信号处理并置似乎特别不明智。

你调用一个函数callError()从信号处理程序内部。目前尚不清楚该函数是否是异步信号安全的。您调用函数calloc() , strcat() ,和free()从信号处理程序内部。这些绝对不是异步信号安全的,并且不能从信号处理程序内部调用。

您为并行构造招募了四个线程,但只提供了三个要运行的部分。

您将所有并行部分放入无限循环中(因此当然程序不会在捕获已安装处理程序的信号时终止)。

您没有始终如一地检查函数调用的返回值。

<小时/>

您的总体策略似乎很困惑。一般来说,执行干净的异步关闭(即导致线程终止操作以响应不同线程或信号处理程序的操作)涉及设置一个共享标志,要关闭的线程定期检查该标志确定是继续还是退出。您可以安全地从信号处理程序设置此类标志,前提是其类型为 volatile sig_atomic_t .

此外,信号处理程序应该执行尽可能少的工作,并且允许它们调用的系统函数仅限于指定的异步信号安全函数。此外,它们可能会使用小堆栈进行操作,您应该小心,不要冒耗尽堆栈的风险。

此外,等到进入 OMP 并行 block 后才安装信号处理程序没有任何优势,并且让信号处理程序将终止消息发送到服务器本身也没有任何优势。

由于您似乎完全满足于将线程专用于信号处理,因此我建议您使用它来接受 SIGINT 同步,通过 sigwait()或其相关功能之一。然后该线程可以触发 OMP 的取消功能 - 请参阅 cancel-var ICV 和 cancel构造。其他线程需要合作 - 请参阅 cancellation point构造。由于您没有提供退出并行部分的其他方法,因此您可以从正常(不是信号处理程序)代码将注销消息发送到服务器,紧随并行区域。

关于c - 捕获SIGINT信号后退出程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43329810/

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