4

嗨,我需要从一个地方跳到另一个地方...

但我想知道哪个更好用,setjmp 或 ucontext,比如:

  • setjmp 和 ucontext 是否可移植?
  • 我的代码使用这些库是线程安全的吗?
  • 为什么用一个代替另一个?
  • 哪个又快又安全?
  • ...(有人请,可以回答我忘记放在这里的未来问题吗?)

请提供我要求的更多信息,例如示例或一些文档...

我在网上搜索过,但我只得到了 C 中的异常处理,比如 setjmp 的例子,我对 ucontex.h 一无所知,我知道它是用于多任务的,它和 pthread 有什么区别?

非常感谢。

4

3 回答 3

5

setjmp是可移植的(ISO C89 和 C99)并且ucontext(在 SUSv3 中已过时并从 SUSv4/POSIX 2008 中删除)不是。但是ucontext在规格上要强大得多。setjmp在实践中,如果您对/和信号处理程序以及备用信号处理堆栈使用讨厌的 hack longjmp,您可以使它们与 . 一样强大ucontext,但它们不是“可移植的”。

两者都不应该用于多线程。为此目的 POSIX 线程(pthread 函数)。我这么说有几个原因:

  • 如果您正在编写线程代码,您不妨让它实际同时运行。我们正在达到非并行计算的速度极限,未来的机器将越来越并行,所以要利用这一点。
  • ucontext已从标准中删除,并且可能在未来的操作系统(甚至某些现有的操作系​​统?)中不受支持
  • 滚动您自己的线程不能对您可能想要使用的库代码透明。它可能会破坏对并发、锁定等做出合理假设的库代码。只要您的多线程是协作的而不是基于异步信号的,这样的问题可能不会太多,但是一旦您深入了解了不可移植性hacks 事情会变得非常脆弱。
  • ...可能还有一些我现在想不起来的原因。:-)
于 2011-04-04T16:41:04.077 回答
1

在可移植性方面,setjmp()可移植到所有托管的 C 实现;这些<ucontext.h>函数是对 POSIX 的 XSI 扩展的一部分——这setjmp()大大提高了可移植性。

可以以setjmp()线程安全的方式使用。在线程程序中使用函数没有多大意义ucontext——您将使用多个线程而不是多个上下文。

如果setjmp()您想从深度嵌套的函数调用中快速返回,请使用(这就是为什么您会发现大多数示例都显示了它用于异常处理的原因)。使用这些ucontext函数来实现用户空间线程或协程(或者根本不使用它们)。

“快速且安全”的问题毫无意义。这些实现通常尽可能快,但它们执行不同的功能,因此无法直接比较(这些ucontext功能做更多的工作,因此通常会稍微慢一些)。

请注意,这些ucontext功能在 POSIX 的两个最新版本中被列为过时。通常应该使用 pthreads 线程函数。

于 2011-04-04T16:36:19.393 回答
0

setjmp/longjmp 仅用于恢复“调用”上下文,因此您只能使用它从子例程链中“快速退出”。根据系统的不同,不同的用途可能会或可能不会起作用,但总的来说,这些功能并不打算做这种事情。所以“ucontext”更好。还可以查看“fibers”(Windows 原生)。这里是一篇文章的链接,可能会有所帮助:

如何实现一个实用的光纤调度器?

再见!

于 2011-04-04T10:53:36.947 回答