.TH MPU_UNLOCKED 3 "Август 2026" "libmpuio" "Руководство программиста LIBMPUIO" .SH ИМЯ mpu_unlocked \- операции LIBMPUIO без неявной блокировки потока .SH БИБЛИОТЕКА Сопутствующая библиотека LIBMPUIO для LIBMPU. .SH ОБЗОР .nf #include int mpu_fgetc_unlocked( mpu_FILE *stream ); int mpu_getc_unlocked( mpu_FILE *stream ); int mpu_getchar_unlocked( void ); int mpu_fputc_unlocked( __mpu_char16_t c, mpu_FILE *stream ); int mpu_putc_unlocked( __mpu_char16_t c, mpu_FILE *stream ); int mpu_putchar_unlocked( __mpu_char16_t c ); __mpu_char16_t *mpu_fgets_unlocked( __mpu_char16_t *s, int n, mpu_FILE *stream ); int mpu_fputs_unlocked( const __mpu_char16_t *s, mpu_FILE *stream ); ssize_t mpu_getdelim_unlocked( __mpu_char16_t **lineptr, size_t *n, __mpu_char16_t delimiter, mpu_FILE *stream ); ssize_t mpu_getline_unlocked( __mpu_char16_t **lineptr, size_t *n, mpu_FILE *stream ); size_t mpu_fread_unlocked( void *ptr, size_t size, size_t nmemb, mpu_FILE *stream ); size_t mpu_fwrite_unlocked( const void *ptr, size_t size, size_t nmemb, mpu_FILE *stream ); int mpu_fflush_unlocked( mpu_FILE *stream ); int mpu_fpurge_unlocked( mpu_FILE *stream ); int mpu_vfprintf_unlocked( mpu_FILE *stream, const __mpu_char16_t *format, va_list args ); int mpu_fprintf_unlocked( mpu_FILE *stream, const __mpu_char16_t *format, ... ); int mpu_vprintf_unlocked( const __mpu_char16_t *format, va_list args ); int mpu_printf_unlocked( const __mpu_char16_t *format, ... ); int mpu_vfscanf_unlocked( mpu_FILE *stream, const __mpu_char16_t *format, va_list args ); int mpu_fscanf_unlocked( mpu_FILE *stream, const __mpu_char16_t *format, ... ); int mpu_vscanf_unlocked( const __mpu_char16_t *format, va_list args ); int mpu_scanf_unlocked( const __mpu_char16_t *format, ... ); int mpu_fileno_unlocked( mpu_FILE *stream ); int mpu_feof_unlocked( mpu_FILE *stream ); int mpu_ferror_unlocked( mpu_FILE *stream ); void mpu_clearerr_unlocked( mpu_FILE *stream ); .fi .SH ОПИСАНИЕ Каждая перечисленная здесь функция выполняет ту же логическую операцию, что и её обычный аналог, но не захватывает и не освобождает mutex потока. .PP Это аналог семейства unlocked stdio в libc. Такие функции прежде всего удобны для объединения нескольких операций под одной явной блокировкой: это позволяет избежать повторных затрат на lock/unlock, сохраняя атомарность относительно других пользователей того же потока. .SH БЛОКИРУЕМЫЕ И UNLOCKED-ФОРМЫ .TS allbox tab(:); l l l. Операция:Блокируемая форма:Unlocked-форма ввод символов:mpu_fgetc/mpu_getc/mpu_getchar:mpu_fgetc_unlocked/mpu_getc_unlocked/mpu_getchar_unlocked вывод символов:mpu_fputc/mpu_putc/mpu_putchar:mpu_fputc_unlocked/mpu_putc_unlocked/mpu_putchar_unlocked ввод/вывод строк:mpu_fgets/mpu_fputs:mpu_fgets_unlocked/mpu_fputs_unlocked сырые двоичные данные:mpu_fread/mpu_fwrite:mpu_fread_unlocked/mpu_fwrite_unlocked сброс:mpu_fflush:mpu_fflush_unlocked очистка буфера:mpu_fpurge:mpu_fpurge_unlocked форматированный вывод:mpu_fprintf/mpu_printf + формы va_list:соответствующие формы _unlocked форматированный ввод:mpu_fscanf/mpu_scanf + формы va_list:соответствующие формы _unlocked дескриптор/состояние:mpu_fileno/mpu_feof/mpu_ferror:соответствующие формы _unlocked очистка ошибки:mpu_clearerr:mpu_clearerr_unlocked .TE .PP Намеренно отсутствуют unlocked-варианты для таких операций, как .BR mpu_fopen (), .BR mpu_fdopen (), .BR mpu_fclose (), позиционирование, настройка буферизации или .BR mpu_ungetc (). Эти API выполняют переходы жизненного цикла/состояния потока, для которых публичный интерфейс предоставляет только синхронизированную форму. .PP .BR mpu_sprintf (), .BR mpu_snprintf (), .BR mpu_sscanf () и их формы va_list работают с памятью UCS-2, принадлежащей вызывающей стороне, а не с потоком .BR mpu_FILE , поэтому stream-unlocked вариант им не требуется. .SH ОБЯЗАТЕЛЬНАЯ ДИСЦИПЛИНА ВЫЗЫВАЮЩЕЙ СТОРОНЫ Unlocked-вызов безопасен только когда никакой другой поток выполнения не может одновременно обращаться к тому же потоку либо когда вызывающая сторона уже владеет блокировкой потока. .PP Обычный шаблон: .nf mpu_flockfile( fp ); mpu_fputs_unlocked( text, fp ); mpu_fputc_unlocked( '\n', fp ); mpu_fflush_unlocked( fp ); mpu_funlockfile( fp ); .fi .PP Mutex потока рекурсивен, поэтому вызов обычной блокируемой операции при удержании явной flock допустим, хотя смысл явной блокировки обычно как раз в использовании unlocked-аналога. .SH ВАЖНЫЕ РАЗЛИЧИЯ .B mpu_fflush_unlocked() требует поток, отличный от NULL, и сбрасывает только его. .B mpu_fflush(NULL) является синхронизированной операцией для всех потоков; для unlocked-формы NULL не имеет значения «все потоки». .PP .B mpu_fpurge_unlocked() имеет в точности ту же семантику отбрасывания данных, что и mpu_fpurge(), но предполагает, что вызывающая сторона уже владеет блокировкой потока или иначе обеспечивает эксклюзивный доступ. .PP Unlocked-функции форматированного I/O используют в точности ту же грамматику форматов, правила размеров MPU, семантику счётчиков, поведение локали, правила отката и ошибки, что и блокируемые аналоги. Отличие состоит только в неявной блокировке потока. .PP Unlocked raw I/O остаётся байтовым. Unlocked text I/O остаётся строгим UCS-2 внутри и UTF-8 на границах реального файла. .PP Обычная точка входа mpu_fileno() захватывает mutex потока; mpu_fileno_unlocked() читает то же состояние дескриптора без его захвата. .SH ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ В точности как документировано для соответствующей обычной функции. .SH ОШИБКИ В точности как документировано для соответствующей обычной функции. Свойство unlocked не отключает проверки и не подавляет ошибки backend. .SH ПОТОКОБЕЗОПАСНОСТЬ Обычные потоковые вызовы внутренне синхронизированы. Unlocked-вызовы небезопасны при параллельном доступе к одному потоку, если приложение не обеспечивает внешнюю синхронизацию. Одновременное использование unlocked- операции и .BR mpu_fclose () для одного потока без синхронизации приложения недопустимо. .SH СМ. ТАКЖЕ .BR libmpuio (3), .BR mpu_flockfile (3), .BR mpu_fgetc (3), .BR mpu_fread (3), .BR mpu_fpurge (3), .BR mpu_printf (3), .BR mpu_scanf (3) .SH ДИНАМИЧЕСКИЙ ВВОД СТРОК .BR mpu_getline_unlocked () и .BR mpu_getdelim_unlocked () имеют ту же семантику выделения памяти, разделителя, EOF, проверки UCS-2 и возвращаемого значения, что и их блокируемые формы. Опускается только неявный захват mutex потока. Вызывающая сторона по-прежнему отвечает за освобождение полученного буфера через free(3).