Являются ли функции в потоке стандартной библиотеки C безопасными?
Где я могу получить окончательный ответ, является ли мой memcpy
(с использованием реализации eglibc, который поставляется с Ubuntu) потокобезопасным? - Честно говоря, я действительно не нашел ясного ДА или НЕТ в документах.
Кстати, с "потокобезопасным" я имею в виду, что безопасно использовать memcpy
одновременно, когда было бы безопасно копировать байт даты для байта одновременно. Это должно быть возможно, по крайней мере, если данные только для чтения копируются в регионы, которые не перекрываются.
В идеале я хотел бы увидеть что-то вроде списков внизу этой страницы в документах компилятора ARM.
Ответы
Ответ 1
Этот список можно найти здесь, в главе 2.9.1 Thread-Safety
: http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_09_01
То есть, это список функций, которые posix не требует потоковой безопасности. Все другие функции должны быть потокобезопасными. Posix включает стандартную библиотеку C и типичные интерфейсы "unix". (Полный список здесь http://pubs.opengroup.org/onlinepubs/9699919799/functions/contents.html)
memcpy() указан posix, но не является частью списка в 2.9.1 и поэтому может считаться потокобезопасным.
Различные среды в Linux, по крайней мере, пытаются реализовать posix в меру своих возможностей. Функции в linux/glibc могут быть потокобезопасными, даже если posix не требует этого, хотя это редко документируется. Для других функций/библиотек, чем у покрытий posix, вы остаетесь с тем, что их авторы задокументировали...
Из того, что я могу сказать, posix приравнивает безопасность потоков с повторной установкой и гарантирует отсутствие внутренних расследований данных. Вы, однако, несете ответственность за возможные внешние рассылки данных - например, чтобы защитить себя от вызова, например. memcpy() с памятью, которая может быть обновлена одновременно.
Ответ 2
Это зависит от функции и того, как вы ее используете.
Возьмем, например, memcpy
, как правило, поточно-безопасный, если вы скопируете данные, где оба источника и адресата являются приватными для одного потока. Если вы пишете данные, которые могут быть прочитаны или записаны другим потоком, они перестают быть потокобезопасными и вам необходимо защитить доступ.
Ответ 3
Если функция glibc не является потокобезопасной, тогда будет отображаться справочная страница, и будет (скорее всего) вариант с безопасным потоком также документирован.
См., например, man strtok
:
СИНТАКСИС #include
char *strtok(char *str, const char *delim);
char *strtok_r(char *str, const char *delim, char **saveptr);
_r
(для "реентерабельного" ) является поточно-безопасным вариантом.
К сожалению, на страницах руководства не говорится о том, что функция является потокобезопасной, но только упоминайте о безопасности потоков, если это проблема.
Как и во всех функциях, если вы укажете на него указатель на общий ресурс, он станет небезопасным. Вам решать ручку блокировки.