英語版
このページの英語版を見る
core.sync.rwmutex
読み取り/書き込みミューテックス・モジュールは、共有読み取りアクセスと相互排他的書き込みアクセスを維持するためのプリミティブを提供する。
相互に排他的な書き込みアクセスを維持するためのプリミティブを提供する。
License:
Authors:
Sean Kelly
- class
ReadWriteMutex
; - このクラスはミューテックスを表す、 しかし、ライタが入ると、他のすべてのリーダとライタはブロックされる。このミューテックスは再帰的ではなく、データへのアクセスのみを保護するためのものであることに注意されたい。 だけであることに注意されたい。 また、デッドロック・チェックは行われていない。 デッドロック・チェックは行われていない。 デッドロック・チェックは行われていない。 その結果、このミューテックスを再帰的に取得しようとすると、デッドロックが発生する可能性がある。 このミューテックスを再帰的に取得しようとすると、呼び出し元がデッドロックに陥る可能性がある。 このミューテックスを再帰的に取得しようとすると、呼び出し元がデッドロック に陥る可能性がある。 しかし実際には、これは問題にはならない。 というのも、単にデータを保護するロックを保持したまま、未知のコードを深く呼び出すことは稀だからである。 を深く呼び出すことはめったにないからである。Examples:
import core.atomic, core.thread, core.sync.semaphore; static void runTest(ReadWriteMutex.Policy policy) { scope mutex = new ReadWriteMutex(policy); scope rdSemA = new Semaphore, rdSemB = new Semaphore, wrSemA = new Semaphore, wrSemB = new Semaphore; shared size_t numReaders, numWriters; void readerFn() { synchronized (mutex.reader) { atomicOp!"+="(numReaders, 1); rdSemA.notify(); rdSemB.wait(); atomicOp!"-="(numReaders, 1); } } void writerFn() { synchronized (mutex.writer) { atomicOp!"+="(numWriters, 1); wrSemA.notify(); wrSemB.wait(); atomicOp!"-="(numWriters, 1); } } void waitQueued(size_t queuedReaders, size_t queuedWriters) { for (;;) { synchronized (mutex.m_commonMutex) { if (mutex.m_numQueuedReaders == queuedReaders && mutex.m_numQueuedWriters == queuedWriters) break; } Thread.yield(); } } scope group = new ThreadGroup; // 2つのreaderを同時に group.create(&readerFn); group.create(&readerFn); rdSemA.wait(); rdSemA.wait(); assert(numReaders == 2); rdSemB.notify(); rdSemB.notify(); group.joinAll(); assert(numReaders == 0); foreach (t; group) group.remove(t); // 同時に1つのwriter group.create(&writerFn); group.create(&writerFn); wrSemA.wait(); assert(!wrSemA.tryWait()); assert(numWriters == 1); wrSemB.notify(); wrSemA.wait(); assert(numWriters == 1); wrSemB.notify(); group.joinAll(); assert(numWriters == 0); foreach (t; group) group.remove(t); // readerとwriterは互いに排他的である group.create(&readerFn); rdSemA.wait(); group.create(&writerFn); waitQueued(0, 1); assert(!wrSemA.tryWait()); assert(numReaders == 1 && numWriters == 0); rdSemB.notify(); wrSemA.wait(); assert(numReaders == 0 && numWriters == 1); wrSemB.notify(); group.joinAll(); assert(numReaders == 0 && numWriters == 0); foreach (t; group) group.remove(t); // writerとreaderは互いに排他的である group.create(&writerFn); wrSemA.wait(); group.create(&readerFn); waitQueued(1, 0); assert(!rdSemA.tryWait()); assert(numReaders == 0 && numWriters == 1); wrSemB.notify(); rdSemA.wait(); assert(numReaders == 1 && numWriters == 0); rdSemB.notify(); group.joinAll(); assert(numReaders == 0 && numWriters == 0); foreach (t; group) group.remove(t); // ポリシーは、キューに入れられたreaderとwritersのどちらが先に進むかを決定する group.create(&writerFn); wrSemA.wait(); group.create(&readerFn); group.create(&writerFn); waitQueued(1, 1); assert(numReaders == 0 && numWriters == 1); wrSemB.notify(); if (policy == ReadWriteMutex.Policy.PREFER_READERS) { rdSemA.wait(); assert(numReaders == 1 && numWriters == 0); rdSemB.notify(); wrSemA.wait(); assert(numReaders == 0 && numWriters == 1); wrSemB.notify(); } else if (policy == ReadWriteMutex.Policy.PREFER_WRITERS) { wrSemA.wait(); assert(numReaders == 0 && numWriters == 1); wrSemB.notify(); rdSemA.wait(); assert(numReaders == 1 && numWriters == 0); rdSemB.notify(); } group.joinAll(); assert(numReaders == 0 && numWriters == 0); foreach (t; group) group.remove(t); } runTest(ReadWriteMutex.Policy.PREFER_READERS); runTest(ReadWriteMutex.Policy.PREFER_WRITERS);
- enum
Policy
: int; - このミューテックスが使用するポリシーを定義する。 現在、2つのポリシーが定義されている。 が定義されている。1つ目は、ミューテックスを保持するリーダがいなくなるまでライタをキューに入れ、その後、ライタを1つずつ通過させる。 ライターを一人ずつ通過させる。 もしあるリーダがミューテックスを取得した場合 を取得した場合、そのリーダが優先される。 ライターがキューに入っていれば、2番目はリーダーをキューに入れる。 ライター は一度に一人ずつ通過し、ライターがいなくなると、キューに入れられたすべてのリーダーに警告が発せられる、 キューに入れられたすべての読者に警告が発せられる。 将来のポリシーでは、リーダとライタの優先順位をより均等なバランスにするかもしれない。 優先される。
PREFER_READERS
- 読者が優先される。 これは作家を飢えさせるかもしれない。
PREFER_WRITERS
- 作家が優先される。 これはリーダを飢えさせるかもしれない。
- nothrow @safe this(Policy
policy
= Policy.PREFER_WRITERS);
shared nothrow @safe this(Policypolicy
= Policy.PREFER_WRITERS); - 与えられたポリシーで読み取り/書き込みミューテックスオブジェクトを初期化する。Parameters:
Policy policy
使用するポリシー。 Throws:エラー時に SyncError を返す。 - nothrow @property @safe Policy
policy
();
shared nothrow @property @safe Policypolicy
(); - このミューテックスで使用されているポリシーを取得する。Returns:このミューテックスが使用するポリシー。
- nothrow @property @safe Reader
reader
();
shared nothrow @property @safe shared(Reader)reader
(); - 関連するミューテックスのリーダー・ロックを表すオブジェクトを取得する。Returns:リーダサブミューテックス。
- nothrow @property @safe Writer
writer
();
shared nothrow @property @safe shared(Writer)writer
(); - 関連付けられたミューテックスのライター・ロックを表すオブジェクトを取得する。Returns:ライター・サブミューテックス。
- class
Reader
: object.Object.Monitor; - このクラスは、それ自体がミューテックスと見なすことができ、次のような用途に使用される。 このクラスは、それ自体がミューテックスと見なすことができ、ミューテックスを包含する読み取りロックのネゴシエーションに使用される。
- nothrow @trusted this(this Q)()
if (is(Q == Reader) || is(Q == shared(Reader))); - 読み取り/書き込みミューテックス・リーダー・プロキシ・オブジェクトを初期化する。
- @trusted void
lock
();
shared @trusted voidlock
(); - 囲んでいるミューテックスの読み取りロックを獲得する。
- @trusted void
unlock
();
shared @trusted voidunlock
(); - 囲んでいるミューテックスの読み取りロックを解放する。
- @trusted bool
tryLock
();
shared @trusted booltryLock
(); - 包含するミューテックスの読み取りロックの獲得を試みる。 ブロックせずにロックを取得できる場合 ブロックせずにロックを取得できる場合、ロックが取得され、trueが返される。 が返される。 取得できない場合は、ロックは取得されず、falseが返される。Returns:ロックが獲得された場合はtrue、獲得されなかった場合はfalseが返される。
- @trusted bool
tryLock
(Durationtimeout
);
shared @trusted booltryLock
(Durationtimeout
); - 囲んでいるミューテックスに対する読み取りロックの獲得を試みる。ブロックせずにロックを取得できた場合は ブロックせずにロックを取得できた場合は、ロックを取得し、trueを返す。 が返される。そうでない場合、"関数"はロックが取得できるか、経過時間がロックを超えるまでブロックする。 ロックが取得できた場合はtrueが返され、取得できなかった場合はfalseが返される。 ロックが取得できた場合はtrueを、関数がタイムアウトした場合はfalseを返す。Parameters:
Duration timeout
ロックを待つ最大時間 Returns:ロックが獲得された場合はtrue、獲得されなかった場合はfalse。
- class
Writer
: object.Object.Monitor; - このクラスは、それ自体がミューテックスと見なすことができ、次のように使用される。 を囲むミューテックスに対して書き込みロックのネゴシエーションを行う。
- nothrow @trusted this(this Q)()
if (is(Q == Writer) || is(Q == shared(Writer))); - 読み取り/書き込みミューテックス・ライター・プロキシ・オブジェクトを初期化する。
- @trusted void
lock
();
shared @trusted voidlock
(); - 囲んでいるミューテックスの書き込みロックを獲得する。
- @trusted void
unlock
();
shared @trusted voidunlock
(); - 囲んでいるミューテックスの書き込みロックを解放する。
- @trusted bool
tryLock
();
shared @trusted booltryLock
(); - 囲んでいるミューテックスの書き込みロックの獲得を試みる。 ブロックせずにロックを取得できる場合 ブロックせずにロックを取得できる場合、ロックが取得され、trueが返される。 が返される。 取得できない場合は、ロックは取得されず、falseが返される。Returns:ロックが取得された場合はtrue、取得されなかった場合はfalseが返される。
- @trusted bool
tryLock
(Durationtimeout
);
shared @trusted booltryLock
(Durationtimeout
); - ミューテックスを包含する書き込みロックの獲得を試みる。ブロックせずにロックを取得できた場合は ブロックせずにロックを取得できた場合は、ロックが取得され、trueが返される。 が返される。そうでない場合、"関数"はロックが取得できるまでブロックする。 ロックが取得できた場合はtrueが返され、取得できなかった場合はfalseが返される。 ロックが取得できた場合はtrueを、関数がタイムアウトした場合はfalseを返す。Parameters:
Duration timeout
ロックを待つ最大時間 Returns:ロックが取得された場合はtrue、取得されなかった場合はfalse。
Copyright © 1999-2024 by the D Language Foundation
DEEPL APIにより翻訳、ところどころ修正。
このページの最新版(英語)
このページの原文(英語)
翻訳時のdmdのバージョン: 2.108.0
ドキュメントのdmdのバージョン: 2.109.1
翻訳日付 :
HTML生成日時:
編集者: dokutoku