.\" -*- coding: UTF-8 -*- .\" Copyright 1993 Giorgio Ciucci (giorgio@crcc.it) .\" .\" SPDX-License-Identifier: Linux-man-pages-copyleft .\" .\" Modified 1996-10-22, Eric S. Raymond .\" Modified 2002-01-08, Michael Kerrisk .\" Modified 2003-04-28, Ernie Petrides .\" Modified 2004-05-27, Michael Kerrisk .\" Modified, 11 Nov 2004, Michael Kerrisk .\" Language and formatting clean-ups .\" Added notes on /proc files .\" 2005-04-08, mtk, Noted kernel version numbers for semtimedop() .\" 2007-07-09, mtk, Added an EXAMPLE code segment. .\" .\"******************************************************************* .\" .\" This file was generated with po4a. Translate the source file. .\" .\"******************************************************************* .TH semop 2 "2 мая 2024 г." "Linux man\-pages 6.8" .SH ИМЯ semop, semtimedop \- операции с семафорами System V .SH LIBRARY Standard C library (\fIlibc\fP, \fI\-lc\fP) .SH СИНТАКСИС .nf \fB#include \fP .P \fBint semop(int \fP\fIsemid\fP\fB, struct sembuf *\fP\fIsops\fP\fB, size_t \fP\fInsops\fP\fB);\fP \fBint semtimedop(int \fP\fIsemid\fP\fB, struct sembuf *\fP\fIsops\fP\fB, size_t \fP\fInsops\fP\fB,\fP \fB const struct timespec *_Nullable \fP\fItimeout\fP\fB);\fP .fi .P .RS -4 Требования макроса тестирования свойств для glibc (см. \fBfeature_test_macros\fP(7)): .RE .P \fBsemtimedop\fP(): .nf _GNU_SOURCE .fi .SH ОПИСАНИЕ С каждым семафором в наборе семафоров System\ V связаны следующие значения: .P .in +4n .EX unsigned short semval; /* semaphore value */ unsigned short semzcnt; /* # waiting for zero */ unsigned short semncnt; /* # waiting for increase */ pid_t sempid; /* PID of process that last modified the semaphore value */ .EE .in .P Вызов \fBsemop\fP() производит операции над выбранными семафорами из набора семафоров \fIsemid\fP. Каждый из элементов \fInsops\fP в массиве, указанном в \fIsops\fP является структурой, которой задаётся операция, выполняемая над отдельным семафором. Элементы этой структуры имеют тип \fIstruct sembuf\fP, который содержит поля: .P .in +4n .EX unsigned short sem_num; /* номер семафора */ short sem_op; /* операция над семафором */ short sem_flg; /* флаги операции */ .EE .in .P Флаги в \fIsem_flg\fP могут иметь значения \fBIPC_NOWAIT\fP и \fBSEM_UNDO\fP. Если указан флаг \fBSEM_UNDO\fP, то при завершении процесса будет выполнена откат операции. .P Набор операций из \fIsops\fP выполняется в \fIпорядке появления в массиве\fP и \fIявляется атомарным\fP, то есть выполняются или все операции, или ни одной. Поведение системного вызова при обнаружении невозможности немедленного выполнения операций зависит от наличия флага \fBIPC_NOWAIT\fP в полях \fIsem_flg\fP отдельных операций, как это описано далее. .P Каждая операция выполняется над \fIsem_num\fP\-тым семафором из набора, где первый семафор имеет номер 0. Есть три типа операций, различающихся значением \fIsem_op\fP. .P If \fIsem_op\fP is a positive integer, the operation adds this value to the semaphore value (\fIsemval\fP). Furthermore, if \fBSEM_UNDO\fP is specified for this operation, the system subtracts the value \fIsem_op\fP from the semaphore adjustment (\fIsemadj\fP) value for this semaphore. This operation can always proceed\[em]it never forces a thread to wait. The calling process must have alter permission on the semaphore set. .P Если значение \fIsem_op\fP равно нулю, то процесс должен иметь права на чтение набора семафоров. Эта операция «ожидания нуля»: если \fIsemval\fP равно нулю, то операция может выполнится сразу. Иначе, если в поле семафора \fIsem_flg\fP указан флаг \fBIPC_NOWAIT\fP, то \fBsemop\fP() завершается с ошибкой и \fIerrno\fP присваивается значение \fBEAGAIN\fP (и ни одна операция из \fIsops\fP не выполняется). Или же \fIsemzcnt\fP (счётчик нитей, ожидающих пока значение семафора не сравнялось с нулём) увеличивается на единицу, а нить переходит в режим ожидания пока не случится одно из: .IP \[bu] 3 Значение \fIsemval\fP станет равным 0, тогда значение \fIsemzcnt\fP уменьшается. .IP \[bu] Набор семафоров удалится: \fBsemop\fP() завершается с ошибкой, а \fIerrno\fP присваивается значение \fBEIDRM\fP. .IP \[bu] Вызывающая нить получит сигнал: значение \fIsemncnt\fP уменьшается и \fBsemop\fP() завершается с ошибкой, а \fIerrno\fP присваивается значение \fBEINTR\fP. .P Если значение \fIsem_op\fP меньше нуля, то процесс должен иметь права на изменение набора семафоров. Если значение \fIsemval\fP больше или равно абсолютному значению \fIsem_op\fP, то операция может выполнятся сразу: абсолютное значение \fIsem_op\fP вычитается из \fIsemval\fP, и, если для этой операции установлен флаг \fBSEM_UNDO\fP, система добавляет абсолютное значение \fIsem_op\fP к значению регулировки (\fIsemadj\fP) семафора. Если абсолютное значение \fIsem_op\fP больше \fIsemval\fP, и в \fIsem_flg\fP указан \fBIPC_NOWAIT\fP, то \fBsemop\fP() завершается с ошибкой, а \fIerrno\fP присваивается значение \fBEAGAIN\fP (и ни одна операция из \fIsops\fP не выполняется). Иначе \fIsemncnt\fP (счётчик нитей, ожидающих увеличения значения семафора) увеличивается на единицу, а нить переходит в режим ожидания пока не случится одно из: .IP \[bu] 3 \fIsemval\fP становится больше или равно абсолютному значению \fIsem_op\fP: операция продолжается как описано выше. .IP \[bu] Набор семафоров удалится из системы: \fBsemop\fP() завершается с ошибкой, а \fIerrno\fP присваивается значение \fBEIDRM\fP. .IP \[bu] Вызывающая нить получит сигнал: значение \fIsemncnt\fP уменьшается и \fBsemop\fP() завершается с ошибкой, а \fIerrno\fP присваивается значение \fBEINTR\fP. .P .\" and .\" .I sem_ctime При успешном выполнении значение \fIsempid\fP для каждого семафора, указанного в массиве, на который указывает \fIsops\fP, устанавливается равным идентификатору вызывающего процесса. Также \fIsem_otime\fP присваивается значение текущего времени. .SS semtimedop() Системный вызов \fBsemtimedop\fP() ведёт себя идентично \fBsemop\fP(), за исключением того, что в случаях, когда вызывающая нить будет спать, длительность этого сна ограничена количеством времени, определяемым структурой \fItimespec\fP, чей адрес передаётся в аргументе \fItimeout\fP. Данное значение интервала будет округлено до точности системных часов, а из\-за задержки при планировании в ядре блокирующий интервал будет немного больше. Если достигнут указанный лимит времени, то \fBsemtimedop\fP() завершится с ошибкой, а \fIerrno\fP устанавливается в \fBEAGAIN\fP (и ни одна из операций в \fIsops\fP не выполняется). Если значение аргумента \fItimeout\fP равно NULL, то \fBsemtimedop\fP() ведёт себя аналогично \fBsemop\fP(). .P Заметим, что если \fBsemtimedop\fP() прерывается сигналом, то вызов завершается с ошибкой \fBEINTR\fP, а содержимое \fItimeout\fP не изменяется. .SH "ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ" On success, \fBsemop\fP() and \fBsemtimedop\fP() return 0. On failure, they return \-1, and set \fIerrno\fP to indicate the error. .SH ОШИБКИ .TP \fBE2BIG\fP Значение аргумента \fInsops\fP больше \fBSEMOPM\fP, максимального количества операций, которое может выполнить один системный вызов. .TP \fBEACCES\fP Вызывающий процесс не имеет прав, требуемых для выполнения указанных операций над семафорами, и не имеет мандата \fBCAP_IPC_OWNER\fP, который управляет его пространством имён IPC. .TP \fBEAGAIN\fP Операция не может быть выполнена немедленно и, либо \fBIPC_NOWAIT\fP был указан в \fIsem_flg\fP, либо истекло время лимита, определённое в \fItimeout\fP. .TP \fBEFAULT\fP Адрес, указанный в \fIsops\fP или \fItimeout\fP, не доступен. .TP \fBEFBIG\fP Для некоторых операций значение \fIsem_num\fP меньше нуля или больше или равно количеству семафоров в наборе. .TP \fBEIDRM\fP Набор семафоров был удалён. .TP \fBEINTR\fP Нить, находясь в режиме ожидания, получила сигнал; смотрите \fBsignal\fP(7). .TP \fBEINVAL\fP Набор семафоров не существует, или значение \fIsemid\fP меньше нуля, или \fInsops\fP имеет не положительное значение. .TP \fBENOMEM\fP Для некоторых операций в поле \fIsem_flg\fP задан флаг \fBSEM_UNDO\fP, и система не может выделить достаточно памяти для структуры откатов. .TP \fBERANGE\fP Для некоторых операций \fIsem_op+semval\fP больше чем \fBSEMVMX\fP, максимального значения \fIsemval\fP (зависит от реализации). .SH СТАНДАРТЫ POSIX.1\-2008. .SH ВЕРСИИ .\" SVr4 documents additional error conditions EINVAL, EFBIG, ENOSPC. Linux 2.5.52 (backported into Linux 2.4.22), glibc 2.3.3. POSIX.1\-2001, SVr4. .SH ПРИМЕЧАНИЯ Структуры процесса \fIsem_undo\fP не наследуются потомками, созданными через \fBfork\fP(2), но они наследуются при выполнении системного вызова \fBexecve\fP(2). .P Вызов \fBsemop\fP() никогда автоматически не перезапускается после прерывания обработчиком сигнала, независимо от установки флага \fBSA_RESTART\fP при настройке обработчика сигнала. .P A semaphore adjustment (\fIsemadj\fP) value is a per\-process, per\-semaphore integer that is the negated sum of all operations performed on a semaphore specifying the \fBSEM_UNDO\fP flag. Each process has a list of \fIsemadj\fP values\[em]one value for each semaphore on which it has operated using \fBSEM_UNDO\fP. When a process terminates, each of its per\-semaphore \fIsemadj\fP values is added to the corresponding semaphore, thus undoing the effect of that process's operations on the semaphore (but see BUGS below). When a semaphore's value is directly set using the \fBSETVAL\fP or \fBSETALL\fP request to \fBsemctl\fP(2), the corresponding \fIsemadj\fP values in all processes are cleared. The \fBclone\fP(2) \fBCLONE_SYSVSEM\fP flag allows more than one process to share a \fIsemadj\fP list; see \fBclone\fP(2) for details. .P Значения \fIsemval\fP, \fIsempid\fP, \fIsemzcnt\fP и \fIsemnct\fP семафора можно получить с помощью соответствующих вызовов \fBsemctl\fP(2). .SS "Ограничения семафоров" Ниже приведены лимиты ресурсов наборов семафоров, влияющие на вызов \fBsemop\fP(): .TP \fBSEMOPM\fP .\" commit e843e7d2c88b7db107a86bd2c7145dc715c058f4 .\" This /proc file is not available in Linux 2.2 and earlier -- MTK .\" See comment in Linux 3.19 source file include/uapi/linux/sem.h Максимальное количество операций, разрешённых для одного вызова \fBsemop\fP(). До версии Linux 3.19, значение по умолчанию было 3. Начиная с Linux 3.19, значение по умолчанию равно 500. В Linux это ограничение можно прочитать и изменить через третье поле \fI/proc/sys/kernel/sem\fP. \fIЗамечание\fP: это ограничение не должно превышать 1000, так как есть риск, что \fBsemop\fP(2) завершится с ошибкой из\-за фрагментации памяти ядра при выделении памяти при копировании массива \fIsops\fP. .TP \fBSEMVMX\fP Максимально допустимое значение \fIsemval\fP: зависит от реализации (32767). .P Реализация не накладывает существенных ограничений на максимальное значение (\fBSEMAEM\fP), на которое можно изменить значение семафора при выходе, максимальное количество системных структур откатываемых операций (\fBSEMMNU\fP) и максимальное количество элементов отката системных параметров на процесс. .SH ОШИБКИ При завершении процесса его набор связанных структур \fIsemadj\fP используется для отката выполненных действий над семафорами, для которых был установлен флаг \fBSEM_UNDO\fP. Это повышает сложность: если одно (или более) этих изменений семафоров привело бы в результате к попытке уменьшить значение семафора ниже нуля, что должно быть сделано в реализации? Одним из возможных решений была бы блокировка до тех пор, пока не выполнятся все изменения семафоров. Однако это нежелательно, так как это привело бы к блокированию процесса на неопределённый срок при его завершении. Другим вариантом является игнорирование сразу всех изменений семафоров (в некоторой степени, аналогично завершению с ошибкой, когда для операции с семафором указан \fBIPC_NOWAIT\fP). В Linux используется третий вариант: уменьшение значения семафора до тех пор, пока это возможно ( т.е. до нуля) и разрешение немедленного завершения процесса. .P .\" The bug report: .\" http://marc.theaimsgroup.com/?l=linux-kernel&m=110260821123863&w=2 .\" the fix: .\" http://marc.theaimsgroup.com/?l=linux-kernel&m=110261701025794&w=2 In Linux 2.6.x, x <= 10, there is a bug that in some circumstances prevents a thread that is waiting for a semaphore value to become zero from being woken up when the value does actually become zero. This bug is fixed in Linux 2.6.11. .SH ПРИМЕРЫ В следующем фрагменте кода используется \fBsemop\fP() для атомарного ожидания момента, когда значение семафора 0 станет равным нулю и последующего увеличения значения семафора на единицу. .P .in +4n .EX struct sembuf sops[2]; int semid; \& /* Code to set \fIsemid\fP omitted */ \& sops[0].sem_num = 0; /* Operate on semaphore 0 */ sops[0].sem_op = 0; /* Wait for value to equal 0 */ sops[0].sem_flg = 0; \& sops[1].sem_num = 0; /* Operate on semaphore 0 */ sops[1].sem_op = 1; /* Increment value by one */ sops[1].sem_flg = 0; \& if (semop(semid, sops, 2) == \-1) { perror("semop"); exit(EXIT_FAILURE); } .EE .in .P A further example of the use of \fBsemop\fP() can be found in \fBshmop\fP(2). .SH "СМОТРИТЕ ТАКЖЕ" \fBclone\fP(2), \fBsemctl\fP(2), \fBsemget\fP(2), \fBsigaction\fP(2), \fBcapabilities\fP(7), \fBsem_overview\fP(7), \fBsysvipc\fP(7), \fBtime\fP(7) .PP .SH ПЕРЕВОД Русский перевод этой страницы руководства разработал Alexander Golubev , Azamat Hackimov , Hotellook, Nikita , Spiros Georgaras , Vladislav , Yuri Kozlov и Иван Павлов . .PP Этот перевод является свободной программной документацией; он распространяется на условиях общедоступной лицензии GNU (GNU General Public License - GPL, .UR https://www.gnu.org/licenses/gpl-3.0.html .UE версии 3 или более поздней) в отношении авторского права, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ. .PP Если вы обнаружите какие-либо ошибки в переводе этой страницы руководства, пожалуйста, сообщите об этом разработчику по его адресу электронной почты или по адресу .MT списка рассылки русских переводчиков .ME .