C setjmp.h и ucontext.h, что лучше?

Привет, мне нужно прыгать с места на другое...

Но я хотел бы знать, что лучше использовать, setjmp или ucontext, например:

  • Переносимы ли setjmp и ucontext?
  • Мой код является потокобезопасным, используя эту библиотеку?
  • Зачем использовать одно вместо другого?
  • Что быстро и безопасно?
  • ...(Кто-нибудь, пожалуйста, может ответить на будущий вопрос, который я забыл поставить здесь?)

Пожалуйста, дайте немного больше информации, которую я прошу, например, примеры или некоторые документы...

У меня был поиск в Интернете, но я получил только обработку исключений в C, например, пример setjmp, и я ничего не нашел о ucontex.h, я понял, что он использовался для многозадачности, в чем разница между ним и pthread?

Большое спасибо.


person drigoSkalWalker    schedule 04.04.2011    source источник


Ответы (3)


setjmp является переносимым (ISO C89 и C99), а ucontext (устарел в SUSv3 и удален из SUSv4/POSIX 2008) — нет. Однако ucontext был значительно мощнее по спецификациям. На практике, если бы вы использовали неприятные хаки с setjmp/longjmp и обработчиками сигналов и альтернативными стеками обработки сигналов, вы могли бы сделать их такими же мощными, как ucontext, но они не были "портативными".

Ни один из них не должен использоваться для многопоточности. Для этого используются потоки POSIX (функции pthread). У меня есть несколько причин говорить это:

  • Если вы пишете многопоточный код, вы могли бы также заставить его выполняться одновременно. Мы приближаемся к пределу скорости непараллельных вычислений, и будущие машины будут все более и более параллельными, так что воспользуйтесь этим преимуществом.
  • ucontext был удален из стандартов и может не поддерживаться в будущих ОС (или даже в некоторых существующих?)
  • Создание собственных потоков невозможно сделать прозрачным для библиотечного кода, который вы, возможно, захотите использовать. Это может нарушить библиотечный код, который делает разумные предположения о параллелизме, блокировке и т. д. Пока ваша многопоточность является кооперативной, а не основанной на асинхронных сигналах, вероятно, не так уж много подобных проблем, но как только вы углубитесь в непереносимые взломы могут стать очень хрупкими.
  • ...и, возможно, еще несколько причин, о которых я сейчас не могу вспомнить. :-)
person R.. GitHub STOP HELPING ICE    schedule 04.04.2011
comment
Во всех смыслах и целях ucontext по-прежнему является «портативным». Поставщики ОС почти не удаляют какой-либо API, который когда-либо был представлен POSIX, а ucontext — это особенно маленький API, и нет причин его удалять. - person fuz; 26.12.2015

Что касается переносимости, setjmp() переносим на все размещенные реализации C; функции <ucontext.h> являются частью расширений XSI для POSIX, что делает setjmp() значительно более переносимым.

Можно использовать setjmp() потокобезопасным способом. Нет особого смысла использовать функции ucontext в многопоточной программе — вы будете использовать несколько потоков, а не несколько контекстов.

Используйте setjmp(), если вы хотите быстро вернуться из глубоко вложенного вызова функции (именно поэтому вы обнаружите, что в большинстве примеров показано его использование для обработки исключений). Используйте функции ucontext для реализации потоков или сопрограмм в пользовательском пространстве (или не используйте их вообще).

Вопрос «быстро и безопасно» не имеет смысла. Реализации обычно настолько быстры, насколько это практически возможно, но они выполняют разные функции, поэтому их нельзя сравнивать напрямую (функции ucontext выполняют больше работы, поэтому обычно они немного медленнее).

Обратите внимание, что функции ucontext указаны как устаревшие в двух последних редакциях POSIX. Вместо этого обычно следует использовать функции многопоточности pthreads.

person caf    schedule 04.04.2011
comment
Насколько я могу судить, функции ucontext были удалены из POSIX 2008, а не просто помечены как устаревшие. Остались только строения, и они были перемещены в signal.h. Они по-прежнему предоставляются через третий аргумент обработчику сигнала SA_SIGINFO (см. мой недавний вопрос и ответ на вопрос о потенциальном использовании). - person R.. GitHub STOP HELPING ICE; 05.04.2011

setjmp/longjmp предназначены только для восстановления «вызывающего» контекста, поэтому вы можете использовать его только для «быстрого выхода» из цепочки подпрограмм. Различные варианты использования могут работать или не работать в зависимости от системы, но в целом эти функции не предназначены для таких вещей. Так что "неконтекст" лучше. Также обратите внимание на «волокна» (родные для Windows). Вот ссылка на статью, которая может быть полезна:

Как реализовать практичный планировщик волокна?

Пока!

person Giuseppe Guerrini    schedule 04.04.2011