5

我希望我的代码能够处理错误情况,例如函数返回不成功。例如pthread_create,通常我使用下面的函数:

int thread_check1;
 pthread_t function;
 thread_check1 = pthread_create( &function, NULL, function_function,  NULL);
if(thread_check1 != 0){
   fprintf(stderr, "pthread_create error\n");
   exit(1);
}

考虑到错误情况,调用相同的函数直到它返回 0(对于这个特定函数)是否正确,如下所示?

thread_check1 = pthread_create( &function, NULL, function_function,  NULL);
while(thread_check1 != 0){
    thread_check1 = pthread_create( &function, NULL, function_function,  NULL);
}

我可以将相同的逻辑应用于返回值的其他 C 函数吗?否则,您将如何建议在不退出程序的情况下处理错误情况(对于函数返回)?

4

4 回答 4

3

可以这样做,但更正确。假设有一个函数f具有不同的返回值。您可以执行以下操作:

tries_left = 1000;
do
{
    ret = f(params);
    if (ret == OK)
        break;
    else if (ret == SOMETHING_UNRECOVERABLE)
        /* break with failure */
    else if (ret == SOMETHING_FIXABLE)
        /* fix params */
    else
        /* sleep a little */
} while (--tries_left);

这里有很多事情需要考虑:

  • 避免无限循环。如果存在本质上的错误,您就不想陷入循环。所以经过一些尝试,你会想要打破和失败。这就是tries_left发挥作用的地方。
  • 如果无法恢复则失败。如果错误告诉您问题无法解决,请停止尝试。例如,如果您尝试安装一个驱动器并且它告诉您/dev/sda6不存在,那么重试是没有意义的。
  • 尝试实际处理问题。在某些情况下,您可以尝试不同的参数。例如,如果您尝试创建备份文件但不能,您可以尝试更改文件的目录或名称,然后重试。
  • 不要使用 100% CPU。如果您想重试,至少在尝试之间留出一些喘息的空间,以解决任何问题,或者至少避免使用最大 CPU。

最后,如果您有不同的功能需要像这样处理,为了避免重复自己,您可以将整个事情放在一个宏中并调用它CHECK_AND_RETRY(f(params));,假设可以理解什么返回值是不可恢复的,什么是可修复的无论功能如何(有点限制,但没有漂亮的解决方案)。

于 2013-01-04T16:35:26.850 回答
1

正如乔已经提到的,这在很大程度上取决于您的要求和您要使用的方法。每当某事失败时,通常都是有原因的。例如,如果malloc返回零,则没有更多可用内存。

在这种情况下尝试获取新内存而不实际使用free通常会导致无限循环,所以这是你不应该做的事情。另一方面,当您想打开一个文件但它当前被另一个进程阻止时,您可以执行类似的操作。

但是,请记住,这样的循环通常会使 CPU 保持忙碌并减慢其他进程/线程的速度。您也可以在当前解决方案之间使用一个东西,并在退出之前尝试几次:

error_count = 0;
thread_check1 = pthread_create( &function, NULL, function_function,  NULL);
while(thread_check1 != 0){
    sleep(1); // wait some time before we try again
    if(++error_count == 10){
        fprintf(stderr, "Could not create thread\n");
        return 1;
    }
    thread_check1 = pthread_create( &function, NULL, function_function,  NULL);
}
于 2013-01-04T16:29:20.380 回答
1

我绝对不建议处理这样的错误。如果出现真正的问题,您将陷入无限循环。一个示例是在文件已在使用时打开它。我会说您应该执行以下操作之一:

  • 打印/记录错误并停止执行。

  • 允许某些错误(在 if 中添加 &&),此示例仅在错误代码为 3 时重试

    如果(thread_check1!= 0){

         If (thread_check1 == 3) retry;
    
于 2013-01-04T16:30:54.037 回答
1

发生故障时应该做什么完全取决于您的要求。通常它取决于错误的类型(致命的、可接受的等)以及它对程序的影响。回到您的示例,未能创建线程可能应该被视为致命错误,因为阻止它创建的问题很可能不会在第二次或第三次尝试时消失(再次,这取决于您的要求和环境)因此不循环是这里可能是更好的方法。再一次,在失败的情况下你是否想退出程序取决于你——你的程序可以在没有这个线程的情况下继续运行吗?如果是,则无需终止程序。否则 - 终止。

于 2013-01-04T16:31:23.867 回答