Как известно, вызовы бывают блокирующими и не блокирующими. По умолчанию read() для сокета отправляет процесс в сон, пока в сокет не придёт сколько-то данных. Он блокирует исполнение. Если включить неблокирующий режим, read() вернётся сразу, и по errno можно будет понять, произошла ли ошибка или просто данных пока нет. Возможно, такой read() понадобится вызвать несколько раз.
Раньше разделения на blocking и non-blocking хватало. Но потом пришли всякие языки со встроенными фиберами, типа Go, где можно писать обычный блокирующийся код, который на самом деле только выглядит блокирующимся, а на самом деле внутри неблокирующийся. Если данных в сокете недостаточно, среда исполнения откладывает текущий фибер и возобновляет какой-нибудь другой, которому данные уже пришли.
Как называть такие вызовы? Каждый раз описывать, что они выглядят блокирующимися, но на самом деле не блокирующиеся, довольно утомительно. Если называть их блокирующими, возникает путаница с вызовами, которые действительно могут заблокировать выполнение процесса, например, чтение файла с диска. Неблокирующимися их тоже называть нельзя, ведь с точки зрения программиста, вызов возвращает значение один раз: либо результат, либо ошибку.
В случае с Go этот вопрос может не стоять насколько остро. Программа на Go запускает несколько системных потоков, и так сглаживает ожидание. Но, скажем, в OpenResty такого нет. Там важно знать, заблокируется ли нить или нет, потому что она одна.