C setjmp.h和ucontext.h,哪个更好?

时间:2011-04-04 09:55:27

标签: c setjmp

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

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

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

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

我在网上搜索过,但是我只在C语言中得到异常处理,就像setjmp的例子一样,我对ucontex.h一无所知,我得知它用于多任务,它与pthread的区别是什么?< / p>

非常感谢。

3 个答案:

答案 0 :(得分:5)

setjmp是可移植的(ISO C89和C99)和ucontext(在SUSv3中过时并从SUSv4 / POSIX 2008中删除)不是。但是ucontext在规范方面要强大得多。在实践中,如果您使用带有setjmp / longjmp的令人讨厌的黑客和信号处理程序以及备用信号处理堆栈,您可以使它们与ucontext一样强大,但它们不是“便携式” ”

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

  • 如果你正在编写线程代码,你也可以让它实际并发运行。我们正在达到非并行计算的速度限制,未来的机器将越来越平行,所以要充分利用它。
  • ucontext已从标准中删除,未来的操作系统可能不受支持(甚至可能不支持某些操作系统?)
  • 滚动自己的线程不能对您可能想要使用的库代码透明。它可能会破坏对并发,锁定等做出合理假设的库代码。只要您的多线程是合作的而不是基于异步信号的,那么可能没有太多这样的问题,但是一旦你深入了解不可移植的问题黑客行为可能会变得非常脆弱。
  • ...可能还有一些我现在想不到的理由。 : - )

答案 1 :(得分:0)

setjmp / longjmp仅用于恢复“调用”上下文,因此您只能将其用于从子例程链中“快速退出”。根据系统的不同,不同的用途可能有效,也可能无效,但通常这些功能不是为了做这种事情。所以“ucontext”更好。还要看看“光纤”(Windows上的原生)。这是指向可能有用的文章的链接:

How to implement a practical fiber scheduler?

再见!

答案 2 :(得分:0)

关于可移植性问题,setjmp()可移植到所有托管的C实现; <ucontext.h>函数是POSIX的XSI扩展的一部分 - 这使得setjmp()更加便携。

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

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

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

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