Можно вспомнить три уровня безопасности потоков, которые я перечислю здесь для удобства.
1) Не безопасно для всех. Небезопасно вызывать функцию одновременно из нескольких потоков. Например, strtok
.
2) Поток безопасен по отношению к системе. Безопасно вызывать функцию одновременно из нескольких потоков, при условии, что разные вызовы работают с разными данными. Например, rand_r
, memcpy
.
3) Потокобезопасен по отношению к данным. Безопасно вызывать функцию одновременно из нескольких потоков, даже работая с одними и теми же данными. Например pthread_mutex_lock
.
rand_r
находится на уровне 2, и в контексте C (в частности, в спецификации POSIX) принято называть этот потокобезопасным.
В некоторых других языках, таких как Java, принято называть уровень 3 «потокобезопасным», а все остальное - «не потокобезопасным». Так, например, java.util.Vector
является "потокобезопасным", а java.util.ArrayList
- "не безопасным для потоков". Конечно, все методы java.util.ArrayList
находятся на уровне 2. Так что программист, пришедший из Java, может естественно назвать rand_r
и memcpy
«не поточно-ориентированными».
В Си соглашение другое, возможно, потому что внутренне синхронизированные структуры данных довольно редки с самого начала. В контексте C вы могли бы спросить «файловые дескрипторы поточно-ориентированы?» И говорить об уровне 3, но когда спрашиваете «эта функция поточно-ориентирована?» это обычно означает уровень 2.