OpenMP并行程序中的信号处理

use*_*610 8 c signals pthreads openmp signal-handling

我有一个使用POSIX计时器(timer_create())的程序.本质上,程序设置一个计时器并开始执行一些冗长的(可能是无限的)计算.当计时器到期并且调用信号处理程序时,处理程序将打印出已经计算的最佳结果并退出程序.

我考虑使用OpenMP并行进行计算,因为它应该加速它.

在pthreads中,有一些特殊功能,例如为我的线程设置信号掩码等.OpenMP是否提供这样的控制,或者我必须接受这样的事实:信号可以传递给OpenMP创建的任何线程吗?

此外,如果我当前在我的代码的并行部分并且我的处理程序被调用,它是否仍然可以安全地杀死application(exit(0);)并执行诸如锁定OpenMP锁之类的操作?

osg*_*sgx 2

OpenMP 3.1 标准没有提及信号。

据我所知,Linux/UNIX 上每个流行的 OpenMP 实现都是基于 pthread 的,因此 OpenMP 线程是 pthread 的线程。并且适用 pthread 和信号的通用规则。

OpenMP 是否提供这样的控制

没有任何具体控制;但你可以尝试使用pthread的控制。唯一的问题是知道使用了多少 OpenMP 线程以及在哪里放置控制语句。

信号可以传递到 OpenMP 创建的任何线程吗?

默认情况下,是的,它将被传递到任何线程。

我的处理程序被称为,

关于信号处理程序的通常规则仍然适用。信号处理程序中允许的函数列于http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html(在页面末尾)

并且printf是不允许的(write是)。如果您知道在发出信号时 printf 未被任何线程使用(例如,并行区域中没有 printf),则可以使用 printf。

它仍然可以安全地终止应用程序吗(exit(0);)

是的,它可以:abort()并且_exit()被处理程序允许。

exit当任何线程执行或时,Linux/Unix 将终止所有线程abort

以及执行诸如锁定 OpenMP 锁之类的操作?

你不应该这样做,但是如果你知道这个锁在信号处理程序运行时不会被锁定,你可以尝试这样做。

!! 更新

有一个采用 OpenMP 信令的示例http://www.cs.colostate.edu/~cs675/OpenMPvsThreads.pdf(“OpenMP与 C/C++ 中的线程”)。简而言之:在处理程序中设置一个标志,并在每次第 N 次循环迭代时在每个线程中添加对此标志的检查。

使基于信号的异常机制适应并行区域

与 Fortran 应用程序相比,C/C++ 应用程序更容易出现这样的情况:程序使用复杂的用户界面。Genehunter 是一个简单的例子,用户可以通过按 control-C 来中断一个家谱的计算,以便它可以继续到有关疾病的临床数据库中的下一个家谱。在串行版本中,过早终止由类似 C++ 的异常机制处理,涉及信号处理程序、setjump 和 longjump。OpenMP 不允许非结构化控制流跨越并行构造边界。我们修改了OpenMP版本中的异常处理,将中断处理程序更改为轮询机制。捕获 control-C 信号的线程设置共享标志。所有线程都通过调用例程 has_hit_interrupt() 在循环开始时检查该标志,如果已设置则跳过迭代。当循环结束时,主机检查标志并可以轻松执行长跳转以完成异常退出(见图1)。