【问题标题】:How pthread returns the fastest result and terminates the slower ones?pthread 如何返回最快的结果并终止较慢的结果?
【发布时间】:2013-06-05 14:50:20
【问题描述】:

我目前正在编写一个程序,主线程将创建三个子线程。这些线程同时运行,我想做的是一旦一个子线程完成,我会检查输出是否正确。如果是,则终止其他两个线程;如果没有,则丢弃该线程的结果,等待其他两个线程的结果。

我正在使用 pthread_create 在主函数中创建三个结果。但我不知道如何使用连接功能。如果我在 main 函数中使用了 3 次 join 函数,它只是一个一个地等待,直到三个线程完成。

我的计划是这样的:

int return_value;

main(){
    pthread_create(&pid[0], NULL, fun0, NULL);
    pthread_create(&pid[1], NULL, fun1, NULL);
    pthread_create(&pid[2], NULL, fun2, NULL);

}

fun0(){
    ...
    if( check the result is right ){
      return_value = result;
      if (pid[1] is running)  pthread_kill( pid[1], SIGTERM );
      if (pid[2] is running)  pthread_kill( pid[2], SIGTERM );
    }

fun1() ...
fun2() ...

函数 0、1 和 2 彼此相似,一旦一个函数得到正确答案,它将杀死其他两个线程。但是,在运行程序时,一旦处理了 pthread_kill,整个程序就终止了,而不仅仅是一个线程。我不知道为什么。

而且我仍然不知道是否还有其他方法可以编写此程序。谢谢你帮我解决这个问题。

【问题讨论】:

    标签: c multithreading pthreads


    【解决方案1】:

    pthread_kill() 函数并非旨在终止线程,就像 kill() 并非旨在终止进程一样。这些函数只是发送信号,它们的名字是不幸的历史副产品。某些信号处理程序会导致进程终止。使用pthread_kill() 允许您选择哪个线程处理信号,但信号处理程序仍将执行完全相同的操作(例如,终止进程)。

    要终止线程,请使用pthread_cancel()。这通常会在下一个取消点终止线程。取消点列在 pthread_cancel() 的手册页中,只有 write()sleep()pthread_testcancel() 等某些函数是取消点。

    但是,如果将线程的可取消类型(pthread_setcanceltype())设置为PTHREAD_CANCEL_ASYNCHRONOUS,则可以随时取消线程。这可能是危险,您必须非常小心。例如,如果您在malloc() 调用过程中取消了一个线程,那么您以后会遇到各种令人讨厌的问题。

    您可能会发现不时测试一个共享变量要容易得多,或者甚至可以使用不同的进程,如果您不再需要它们,您可以使用 kill()。取消一个线程很棘手。

    总结

    1. 最简单的选择是在每个线程中测试一个变量,看看是否应该取消它。

    2. 如果这不起作用,我的下一个建议是使用fork() 而不是pthread_create(),之后您可以使用kill()

    3. 如果你想玩火,请使用异步pthread_cancel()。这可能会在你的脸上爆炸。您将不得不花费数小时的宝贵时间来寻找错误并试图弄清楚如何正确地进行清理。你会失眠,你的猫会因为忽视而死。

    【讨论】:

    • 幸好我没有养猫狗。但我想试试你的第一种方法。顺便说一句,如果这个问题只发生在 C 中?例如我相信在 C# 中,一旦一个线程完成,就会产生一个信号,以便我可以关闭其他线程。
    • @stcheng:这与 C 或 C# 无关,这与 pthreads 有关。您可以在许多不同的语言中使用 pthread,包括 C。
    • 所以在 c# 中的线程库 System.Threading 不是 pthread 吗?
    • @stcheng:System.Threading 是 System.Threading。 pthreads就是pthreads。它们都是 API。每个 API 都可能使用其他 API 来实现。
    • 我同意只测试一个所有线程共有的变量,并让每个线程优雅地完成(从线程函数返回)。您可以使用普通变量或条件变量 (pthread_cond_t)。另外,我认为最好在互斥锁 (pthread_mutex_t) 块中访问这个公共变量以避免竞争条件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-18
    • 1970-01-01
    • 2015-05-09
    • 1970-01-01
    • 1970-01-01
    • 2012-05-06
    相关资源
    最近更新 更多