Man page - semop(2)

Packages contains this manual

Available languages:

en fr pl ja ru

Manual

SEMOP

名 前
書 式
説 明
semtimedop()
返 り 値
エ ラ ー
バ ー ジ ョ ン
準 拠
注 意
セ マ フ ォ の 上 限
バ グ

関 連 項 目
こ の 文 書 に つ い て

名 前

semop, semtimedop - System V セ マ フ ォ の 操 作

書 式

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

int semop(int semid , struct sembuf * sops , size_t nsops );

int semtimedop(int semid , struct sembuf * sops , size_t nsops ,
const struct timespec *
timeout );

glibc 向 け の 機 能 検 査 マ ク ロ の 要 件 ( feature_test_macros (7) 参 照 ):

semtimedop (): _GNU_SOURCE

説 明

System V セ マ フ ォ 集 合 (semaphore set) の メ ン バ ー の 各 セ マ フ ォ は 以 下 の 関 連 情 報 を 持 っ て い る :

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

semop () は semid で 指 定 さ れ た セ マ フ ォ 集 合 の 選 択 さ れ た セ マ フ ォ に 対 し て 操 作 を 行 う 。 sops nsops 個 の 要 素 の 配 列 を 指 し 、 配 列 の 各 要 素 は 個 々 の セ マ フ ォ に 対 す る 操 作 を 示 す 構 造 体 で あ る 。 そ の 型 は struct sembuf で 、 次 の メ ン バ を 持 つ :

unsigned short sem_num; /* セ マ フ ォ 番 号 */
short sem_op; /* セ マ フ ォ 操 作 */
short sem_flg; /* 操 作 フ ラ グ */

sem_flg に は IPC_NOWAIT SEM_UNDO が 設 定 で き る 。 SEM_UNDO が 指 定 さ れ た 操 作 は 、 そ の プ ロ セ ス が 終 了 し た 時 に 自 動 的 に 取 り 消 さ れ る 。

sops に 含 ま れ る 操 作 の 集 合 は 、 配 列 の 順 序 で 、 ア ト ミ ッ ク に 実 行 さ れ る 。 す な わ ち 、 全 て の 操 作 が 完 全 に 実 行 さ れ る か 、 全 く 実 行 さ れ な い か の ど ち ら か と な る 。 全 て の 操 作 が 直 ち に 実 行 で き な い 場 合 の こ の シ ス テ ム コ ー ル の 振 る 舞 い は 個 々 の 操 作 の sem_flg フ ィ ー ル ド に IPC_NOWAIT が 存 在 す る か に よ っ て 決 ま り 、 後 述 の よ う に な る 。

そ れ ぞ れ の 操 作 は セ マ フ ォ 集 合 の sem_num 番 目 の セ マ フ ォ に 対 し て 実 行 さ れ る 。 セ マ フ ォ 集 合 の 最 初 の セ マ フ ォ に は 番 号 0 が 振 ら れ る 。 そ し て 操 作 は 三 種 類 あ り 、 sem_op の 値 で 区 別 さ れ る 。

sem_op が 正 の 整 数 の 場 合 、 そ の 値 を セ マ フ ォ の 値 ( semval ) に 加 算 す る 。 さ ら に 、 こ の 操 作 で SEM_UNDO が 指 定 さ れ て い た 場 合 は 、 シ ス テ ム は こ の セ マ フ ォ の の 調 整 値 ( semadj ) か ら 値 sem_op を 減 算 す る 。 こ の 操 作 は 必 ず 実 行 で き 、 ス レ ッ ド の 停 止 は 起 こ ら な い 。 呼 び 出 し 元 プ ロ セ ス は 対 象 の セ マ フ ォ 集 合 を 変 更 す る 許 可 が な け れ ば な ら な い 。

sem_op が 0 の 場 合 、 「 ゼ ロ ま で 待 つ 」 操 作 で あ る 。 こ の 場 合 、 プ ロ セ ス は そ の セ マ フ ォ 集 合 に 対 す る 読 み 込 み 許 可 が な け れ ば な ら な い 。 semval が 0 な ら ば 、 操 作 は 直 ち に 行 わ れ る 。 semval が 0 で な い 場 合 、 sem_flg IPC_NOWAIT が 指 定 さ れ て い れ ば 、 semop () は 失 敗 し 、 errno EAGAIN が 設 定 さ れ る (こ の と き sops に 対 す る 操 作 は 全 く 実 行 さ れ な い )。 sem_flg IPC_NOWAIT が 指 定 さ れ て い な い 場 合 、 semzcnt (セ マ フ ォ 値 が 0 に な る の を 待 っ て い る ス レ ッ ド の 数 ) を 1 増 加 さ せ て 、 以 下 の い ず れ か が 起 こ る ま で ス レ ッ ド を 停 止 (sleep) す る 。

semval が 0 に な っ た : こ の と き semzcnt の 値 は 1 減 算 さ れ る 。

セ マ フ ォ 集 合 が 削 除 さ れ た : こ の と き semop () は 失 敗 し 、 errno EIDRM が 設 定 さ れ る 。

呼 び 出 し 元 ス レ ッ ド が シ グ ナ ル を 捕 獲 し た : こ の と き semzcnt の 値 は 1 減 算 さ れ 、 semop () は 失 敗 し errno EINTR が 設 定 さ れ る 。

sem_op が 0 未 満 の 場 合 、 プ ロ セ ス に は そ の セ マ フ ォ 集 合 を 変 更 す る 許 可 が な け れ ば な ら な い 。 semval sem_op の 絶 対 値 以 上 の 場 合 は 、 操 作 は 直 ち に 実 行 さ れ る : semval か ら sem_op の 絶 対 値 を 減 算 し 、 さ ら に 、 こ の 操 作 に SEM_UNDO が 指 定 さ れ て い る 場 合 は 、 こ の セ マ フ ォ の 調 整 値 ( semadj ) に sem_op の 絶 対 値 を 加 算 す る 。 semval sem_op の 絶 対 値 よ り 小 さ く 、 sem_flg IPC_NOWAIT が 指 定 さ れ た 場 合 は 、 semop () は 失 敗 し 、 errno EAGAIN が 設 定 さ れ る (こ の と き sops の 操 作 は 全 く 実 行 さ れ な い )。 semval sem_op の 絶 対 値 よ り 小 さ く 、 IPC_WAIT が 指 定 さ れ て い な い 場 合 は 、 semncnt (こ の セ マ フ ォ の 値 が 増 加 す る の を 待 っ て い る ス レ ッ ド 数 の カ ウ ン タ ー ) を 1 増 加 さ せ て 、 以 下 の い ず れ か が 起 こ る ま で ス レ ッ ド を 停 止 (sleep) す る 。

semval sem_op の 絶 対 値 以 上 に な っ た 。 こ の 時 点 で 、 操 作 は 上 述 の 通 り 実 行 さ れ る 。

セ マ フ ォ 集 合 が シ ス テ ム か ら 削 除 さ れ た : こ の と き semop () は 失 敗 し errno EIDRM が 設 定 さ れ る 。

呼 び 出 し た ス レ ッ ド が シ グ ナ ル を 捕 獲 し た : こ の と き semncnt が 1 減 算 さ れ 、 semop () は 失 敗 し errno EINTR が 設 定 さ れ る 。

操 作 が 成 功 し た 場 合 、 sops が 指 す 配 列 に よ っ て 操 作 対 象 と な っ た 各 セ マ フ ォ の sempid メ ン バ ー に は 呼 び 出 し 元 の プ ロ セ ス ID が 設 定 さ れ る 。 さ ら に sem_otime に 現 在 時 刻 が 設 定 さ れ る 。

semtimedop()

semtimedop () 関 数 の 振 る 舞 い は semop () と 全 く 同 じ だ が 、 呼 び 出 し 元 ス レ ッ ド が 停 止 す る 場 合 、 停 止 期 間 の 上 限 が timeout 引 数 の 指 す timespec 構 造 体 で 指 定 さ れ た 時 間 と な る 点 だ け が 異 な る (こ の 停 止 期 間 は シ ス テ ム ク ロ ッ ク の 粒 度 に 切 り 上 げ ら れ 、 カ ー ネ ル の ス ケ ジ ュ ー リ ン グ 遅 延 に よ り 、 こ の 停 止 期 間 は 少 し だ け 長 く な る 可 能 性 が あ る )。 指 定 し た 制 限 時 間 に 達 し た 場 合 は 、 semtimedop () は 失 敗 し 、 errno EAGAIN が 設 定 さ れ る (こ の と き sops の 操 作 は 実 行 さ れ な い )。 timeout 引 数 が NULL の 場 合 、 semtimedop () 関 数 の 振 る 舞 い は semop () 関 数 と 全 く 同 じ に な る 。

semtimedop () が シ グ ナ ル に よ り 割 り 込 ま れ た 場 合 、 呼 び 出 し は エ ラ ー EINTR で 失 敗 し 、 timeout の 内 容 は 変 更 さ れ な い ま ま と な る 点 に 注 意 す る こ と 。

返 り 値

成 功 し た 場 合 、 semop () と semtimedop () は 0 を 返 す 。 そ う で な け れ ば -1 を 返 し 、 エ ラ ー を 示 す errno を 設 定 す る 。

エ ラ ー

失 敗 し た 場 合 、 errno に 以 下 の ど れ か が 設 定 さ れ る :

E2BIG

nsops 引 数 が SEMOPM よ り 大 き い 。 SEMOPM は 一 回 の シ ス テ ム コ ー ル で 許 さ れ る 操 作 の 最 大 個 数 で あ る 。

EACCES

The calling process does not have the permissions required to perform the specified semaphore operations, and does not have the CAP_IPC_OWNER capability in the user namespace that governs its IPC namespace.

EAGAIN

操 作 を 直 ち に 処 理 す る こ と が で き ず 、 か つ sem_flg IPC_NOWAIT が 指 定 さ れ て い る か timeout で 指 定 さ れ た 制 限 時 間 が 経 過 し た 。

EFAULT

引 数 sops timeout が 指 し て い る ア ド レ ス に ア ク セ ス で き な い 。

EFBIG

あ る 操 作 で 、 sem_num の 値 が 0 未 満 か 、 集 合 内 の セ マ フ ォ の 数 以 上 で あ る 。

EIDRM

セ マ フ ォ 集 合 が 削 除 さ れ た 。

EINTR

こ の シ ス テ ム コ ー ル で 停 止 し て い る 時 に ス レ ッ ド が シ グ ナ ル を 捕 獲 し た 。 single (7) 参 照 。

EINVAL

セ マ フ ォ 集 合 が 存 在 し な い か 、 semid が 0 未 満 で あ る か 、 nsops が 正 の 数 で な い 。

ENOMEM

あ る 操 作 で sem_flg SEM_UNDO が 指 定 さ れ た が 、 シ ス テ ム に ア ン ド ゥ 構 造 体 に 割 り 当 て る 十 分 な メ モ リ ー が な い 。

ERANGE

あ る 操 作 で sem_op+semval SEMVMX よ り 大 き い 。 SEMVMX semval の 最 大 値 で 、 そ の 値 は 実 装 依 存 で あ る 。

バ ー ジ ョ ン

semtimedop () は Linux 2.5.52 で 初 め て 登 場 し 、 そ れ か ら カ ー ネ ル 2.4.22 に も 移 植 さ れ た 。 semtimedop () の glibc で の サ ポ ー ト は バ ー ジ ョ ン 2.3.3 で 初 め て 登 場 し た 。

準 拠

POSIX.1-2001, POSIX.1-2008, SVr4.

注 意

Linux や POSIX の 全 て の バ ー ジ ョ ン で は 、 <sys/types.h> <sys/ipc.h> の イ ン ク ル ー ド は 必 要 な い 。 し か し な が ら 、 い く つ か の 古 い 実 装 で は こ れ ら の ヘ ッ ダ ー フ ァ イ ル の イ ン ク ル ー ド が 必 要 で あ り 、 SVID で も こ れ ら の イ ン ク ル ー ド を す る よ う に 記 載 さ れ て い る 。 こ の よ う な 古 い シ ス テ ム へ の 移 植 性 を 意 図 し た ア プ リ ケ ー シ ョ ン で は こ れ ら の フ ァ イ ル を イ ン ク ル ー ド す る 必 要 が あ る か も し れ な い 。

あ る プ ロ セ ス の sem_undo 構 造 体 は fork (2) で 生 成 さ れ た 子 プ ロ セ ス に は 継 承 さ れ な い が 、 execve (2) シ ス テ ム コ ー ル の 場 合 は 継 承 さ れ る 。

semop () は シ グ ナ ル ハ ン ド ラ ー に よ っ て 中 断 さ れ た 後 に 、 決 し て 自 動 的 に 再 開 す る こ と は な い 。 た と え シ グ ナ ル ハ ン ド ラ ー の 設 定 時 に SA_RESTART フ ラ グ が セ ッ ト さ れ て い て も 再 開 す る こ と は な い

セ マ フ ォ の 調 整 値 ( semadj ) は 、 プ ロ セ ス 毎 の セ マ フ ォ 毎 の 整 数 で 、 SEM_UNDO フ ラ グ を 指 定 し て 行 わ れ た 、 セ マ フ ォ に 対 す る す べ て の 操 作 の 合 計 値 を 反 転 し た も の で あ る 。 各 プ ロ セ ス は semadj の 値 の リ ス ト を 保 持 す る — リ ス ト の そ れ ぞ れ の 値 は SEM_UNDO を 使 っ て 操 作 が 行 わ れ た 個 々 の セ マ フ ォ に 対 応 す る 。 プ ロ セ ス が 終 了 す る 際 、 セ マ フ ォ 毎 の semadj の 各 々 の 値 が 対 応 す る セ マ フ ォ に 加 算 さ れ る 。 こ れ に よ り 、 そ の プ ロ セ ス が そ の セ マ フ ォ に 対 し て 行 っ た 操 作 の 影 響 が 取 り 消 さ れ る (た だ し 、 下 記 の 「 バ グ 」 を 参 照 )。 semctl (2) の SETVAL SETALL を 使 っ て セ マ フ ォ の 値 が 直 接 設 定 さ れ た 場 合 、 す べ て の プ ロ セ ス の 対 応 す る semadj の 値 が ク リ ア さ れ る 。 clone (2) の CLONE_SYSVSEM フ ラ グ を 使 う と 、 複 数 の プ ロ セ ス が ひ と つ の semadj リ ス ト を 共 有 で き る 。 詳 細 は clone (2) を 参 照 。

あ る セ マ フ ォ の semval , sempid , semzcnt , semnct の 値 は い ず れ も 、 適 切 な 操 作 を 指 定 し て semctl (2) を 呼 び 出 す こ と で 取 得 で き る 。

セ マ フ ォ の 上 限

セ マ フ ォ 集 合 の リ ソ ー ス に 関 す る 制 限 の う ち 、 semop () に 影 響 を 及 ぼ す も の を 以 下 に 挙 げ る :

SEMOPM

Maximum number of operations allowed for one semop () call. Before Linux 3.19, the default value for this limit was 32. Since Linux 3.19, the default value is 500. On Linux, this limit can be read and modified via the third field of /proc/sys/kernel/sem . Note : this limit should not be raised above 1000, because of the risk of that semop () fails due to kernel memory fragmentation when allocating memory to copy the sops array.

SEMVMX

semval が 取 り 得 る 最 大 値 : 実 装 依 存 (32767)。

以 下 の 値 に 関 し て は 実 装 依 存 の 制 限 は な い 。 終 了 時 の 調 整 (adjust on exit) の 最 大 値 ( SEMAEM )、 シ ス テ ム 全 体 の ア ン ド ゥ 構 造 体 の 最 大 数 ( SEMMNU )、 プ ロ セ ス あ た り の ア ン ド ゥ 構 造 体 の 最 大 数 。

バ グ

プ ロ セ ス が 終 了 す る 際 、 プ ロ セ ス に 対 応 す る semadj の 集 合 を 使 っ て 、 SEM_UNDO フ ラ グ 付 き で 実 行 さ れ た 全 て の セ マ フ ォ 操 作 の 影 響 を 取 り 消 す 。 こ れ に よ り あ る 問 題 が 発 生 す る : こ れ ら の セ マ フ ォ の 調 整 を 行 っ て い る と 、 中 に は セ マ フ ォ の 値 が 0 未 満 の 値 に し よ う と す る 場 合 が 出 て く る 。 こ の よ う な 場 合 、 ど の よ う に 実 装 す る べ き か ? ひ と つ の 考 え ら れ る 手 法 は 、 全 て の セ マ フ ォ 調 整 が 実 行 さ れ る ま で 停 止 す る こ と で あ る 。 し か し 、 こ の 方 法 で は プ ロ セ ス の 終 了 が 長 時 間 に わ た っ て 停 止 さ れ る こ と が あ る の で 望 ま し く な い 。 し か も ど れ く ら い 長 時 間 に な る か は 分 か ら な い 。 別 の 選 択 肢 と し て 、 こ の よ う な セ マ フ ォ 調 整 を 完 全 に 無 視 し て し ま う 方 法 が あ る (こ れ は セ マ フ ォ 操 作 と し て IPC_NOWAIT が 指 定 す る の と 少 し 似 て い る )。 Linux は 第 三 の 手 法 を 採 用 し て い る : セ マ フ ォ の 値 を 出 来 る だ け (つ ま り 0 ま で ) 減 少 さ せ て 、 プ ロ セ ス の 終 了 を 直 ち に 続 行 で き る よ う に し て い る 。

カ ー ネ ル 2.6.x (x <= 10) に は 、 あ る 状 況 に お い て セ マ フ ォ 値 が 0 に な る の を 待 っ て い る ス レ ッ ド が 、 セ マ フ ォ 値 が 実 際 に 0 に な っ た と き に 起 床 (wake up) さ れ な い 、 と い う バ グ が あ る 。 こ の バ グ は カ ー ネ ル 2.6.11 で 修 正 さ れ て い る 。

以 下 の 部 分 的 な コ ー ド は 、 セ マ フ ォ 0 の 値 が 0 に な る の を 待 っ て か ら 、 セ マ フ ォ の 値 を 1 加 算 す る 処 理 を 、 semop () を 使 っ て ア ト ミ ッ ク (atomically) に 行 う 。

struct sembuf sops[2];
int semid;

/* Code to set semid 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);
}

A further example of the use of semop () can be found in shmop (2).

関 連 項 目

clone (2), semctl (2), semget (2), sigaction (2), capabilities (7), sem_overview (7), sysvipc (7), time (7)

こ の 文 書 に つ い て

こ の man ペ ー ジ は Linux man-pages プ ロ ジ ェ ク ト の リ リ ー ス 5.10 の 一 部 で あ る 。 プ ロ ジ ェ ク ト の 説 明 と バ グ 報 告 に 関 す る 情 報 は https://www.kernel.org/doc/man-pages/ に 書 か れ て い る 。