ReaderWriterLock 클래스

정의

단일 작성기 및 다중 판독기를 지원하는 잠금을 정의합니다.Defines a lock that supports single writers and multiple readers.

public ref class ReaderWriterLock sealed : System::Runtime::ConstrainedExecution::CriticalFinalizerObject
public ref class ReaderWriterLock sealed
public sealed class ReaderWriterLock : System.Runtime.ConstrainedExecution.CriticalFinalizerObject
public sealed class ReaderWriterLock
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class ReaderWriterLock : System.Runtime.ConstrainedExecution.CriticalFinalizerObject
type ReaderWriterLock = class
    inherit CriticalFinalizerObject
type ReaderWriterLock = class
[<System.Runtime.InteropServices.ComVisible(true)>]
type ReaderWriterLock = class
    inherit CriticalFinalizerObject
Public NotInheritable Class ReaderWriterLock
Inherits CriticalFinalizerObject
Public NotInheritable Class ReaderWriterLock
상속
ReaderWriterLock
상속
ReaderWriterLock
특성

예제

다음 예제에서는를 사용 하 여 ReaderWriterLock resource 동시에 읽고 여러 스레드에 의해 독점적으로 작성 되는 공유 리소스 (명명 된 정수 값)를 보호 하는 방법을 보여 줍니다.The following example demonstrates how to use a ReaderWriterLock to protect a shared resource, an integer value named resource, that is read concurrently and written exclusively by multiple threads. ReaderWriterLock 모든 스레드에 표시 되도록 클래스 수준에서 선언 됩니다.Note that the ReaderWriterLock is declared at the class level so that it is visible to all threads.

// This example shows a ReaderWriterLock protecting a shared
// resource that is read concurrently and written exclusively
// by multiple threads.
// The complete code is located in the ReaderWriterLock
// class topic.
using namespace System;
using namespace System::Threading;
public ref class Test
{
public:

   // Declaring the ReaderWriterLock at the class level
   // makes it visible to all threads.
   static ReaderWriterLock^ rwl = gcnew ReaderWriterLock;

   // For this example, the shared resource protected by the
   // ReaderWriterLock is just an integer.
   static int resource = 0;

   literal int numThreads = 26;
   static bool running = true;

   // Statistics.
   static int readerTimeouts = 0;
   static int writerTimeouts = 0;
   static int reads = 0;
   static int writes = 0;
   static void ThreadProc()
   {
      Random^ rnd = gcnew Random;

      // As long as a thread runs, it randomly selects
      // various ways to read and write from the shared
      // resource. Each of the methods demonstrates one
      // or more features of ReaderWriterLock.
      while ( running )
      {
         double action = rnd->NextDouble();
         if ( action < .8 )
                  ReadFromResource( 10 );
         else
         if ( action < .81 )
                  ReleaseRestore( rnd, 50 );
         else
         if ( action < .90 )
                  UpgradeDowngrade( rnd, 100 );
         else
                  WriteToResource( rnd, 100 );
      }
   }


   // Shows how to request and release a reader lock, and
   // how to handle time-outs.
   static void ReadFromResource( int timeOut )
   {
      try
      {
         rwl->AcquireReaderLock( timeOut );
         try
         {

            // It is safe for this thread to read from
            // the shared resource.
            Display( String::Format( "reads resource value {0}", resource ) );
            Interlocked::Increment( reads );
         }
         finally
         {

            // Ensure that the lock is released.
            rwl->ReleaseReaderLock();
         }

      }
      catch ( ApplicationException^ )
      {

         // The reader lock request timed out.
         Interlocked::Increment( readerTimeouts );
      }

   }


   // Shows how to request and release the writer lock, and
   // how to handle time-outs.
   static void WriteToResource( Random^ rnd, int timeOut )
   {
      try
      {
         rwl->AcquireWriterLock( timeOut );
         try
         {

            // It is safe for this thread to read or write
            // from the shared resource.
            resource = rnd->Next( 500 );
            Display( String::Format( "writes resource value {0}", resource ) );
            Interlocked::Increment( writes );
         }
         finally
         {

            // Ensure that the lock is released.
            rwl->ReleaseWriterLock();
         }

      }
      catch ( ApplicationException^ )
      {

         // The writer lock request timed out.
         Interlocked::Increment( writerTimeouts );
      }

   }


   // Shows how to request a reader lock, upgrade the
   // reader lock to the writer lock, and downgrade to a
   // reader lock again.
   static void UpgradeDowngrade( Random^ rnd, int timeOut )
   {
      try
      {
         rwl->AcquireReaderLock( timeOut );
         try
         {

            // It is safe for this thread to read from
            // the shared resource.
            Display( String::Format( "reads resource value {0}", resource ) );
            Interlocked::Increment( reads );

            // If it is necessary to write to the resource,
            // you must either release the reader lock and
            // then request the writer lock, or upgrade the
            // reader lock. Note that upgrading the reader lock
            // puts the thread in the write queue, behind any
            // other threads that might be waiting for the
            // writer lock.
            try
            {
               LockCookie lc = rwl->UpgradeToWriterLock( timeOut );
               try
               {

                  // It is safe for this thread to read or write
                  // from the shared resource.
                  resource = rnd->Next( 500 );
                  Display( String::Format( "writes resource value {0}", resource ) );
                  Interlocked::Increment( writes );
               }
               finally
               {

                  // Ensure that the lock is released.
                  rwl->DowngradeFromWriterLock( lc );
               }

            }
            catch ( ApplicationException^ )
            {

               // The upgrade request timed out.
               Interlocked::Increment( writerTimeouts );
            }


            // When the lock has been downgraded, it is
            // still safe to read from the resource.
            Display( String::Format( "reads resource value {0}", resource ) );
            Interlocked::Increment( reads );
         }
         finally
         {

            // Ensure that the lock is released.
            rwl->ReleaseReaderLock();
         }

      }
      catch ( ApplicationException^ )
      {

         // The reader lock request timed out.
         Interlocked::Increment( readerTimeouts );
      }

   }


   // Shows how to release all locks and later restore
   // the lock state. Shows how to use sequence numbers
   // to determine whether another thread has obtained
   // a writer lock since this thread last accessed the
   // resource.
   static void ReleaseRestore( Random^ rnd, int timeOut )
   {
      int lastWriter;
      try
      {
         rwl->AcquireReaderLock( timeOut );
         try
         {

            // It is safe for this thread to read from
            // the shared resource. Cache the value. (You
            // might do this if reading the resource is
            // an expensive operation.)
            int resourceValue = resource;
            Display( String::Format( "reads resource value {0}", resourceValue ) );
            Interlocked::Increment( reads );

            // Save the current writer sequence number.
            lastWriter = rwl->WriterSeqNum;

            // Release the lock, and save a cookie so the
            // lock can be restored later.
            LockCookie lc = rwl->ReleaseLock();

            // Wait for a random interval (up to a
            // quarter of a second), and then restore
            // the previous state of the lock. Note that
            // there is no timeout on the Restore method.
            Thread::Sleep( rnd->Next( 250 ) );
            rwl->RestoreLock( lc );

            // Check whether other threads obtained the
            // writer lock in the interval. If not, then
            // the cached value of the resource is still
            // valid.
            if ( rwl->AnyWritersSince( lastWriter ) )
            {
               resourceValue = resource;
               Interlocked::Increment( reads );
               Display( String::Format( "resource has changed {0}", resourceValue ) );
            }
            else
            {
               Display( String::Format( "resource has not changed {0}", resourceValue ) );
            }
         }
         finally
         {

            // Ensure that the lock is released.
            rwl->ReleaseReaderLock();
         }

      }
      catch ( ApplicationException^ )
      {

         // The reader lock request timed out.
         Interlocked::Increment( readerTimeouts );
      }

   }


   // Helper method briefly displays the most recent
   // thread action. Comment out calls to Display to
   // get a better idea of throughput.
   static void Display( String^ msg )
   {
      Console::Write( "Thread {0} {1}.       \r", Thread::CurrentThread->Name, msg );
   }

};


int main()
{
   array<String^>^args = Environment::GetCommandLineArgs();

   // Start a series of threads. Each thread randomly
   // performs reads and writes on the shared resource.
   array<Thread^>^t = gcnew array<Thread^>(Test::numThreads);
   for ( int i = 0; i < Test::numThreads; i++ )
   {
      t[ i ] = gcnew Thread( gcnew ThreadStart( Test::ThreadProc ) );
      t[ i ]->Name = gcnew String( Convert::ToChar( i + 65 ),1 );
      t[ i ]->Start();
      if ( i > 10 )
            Thread::Sleep( 300 );

   }

   // Tell the threads to shut down, then wait until they all
   // finish.
   Test::running = false;
   for ( int i = 0; i < Test::numThreads; i++ )
   {
      t[ i ]->Join();

   }

   // Display statistics.
   Console::WriteLine( "\r\n {0} reads, {1} writes, {2} reader time-outs, {3} writer time-outs.", Test::reads, Test::writes, Test::readerTimeouts, Test::writerTimeouts );
   Console::WriteLine( "Press ENTER to exit." );
   Console::ReadLine();
   return 0;
}

// The complete code is located in the ReaderWriterLock class topic.
using System;
using System.Threading;

public class Example
{
   static ReaderWriterLock rwl = new ReaderWriterLock();
   // Define the shared resource protected by the ReaderWriterLock.
   static int resource = 0;

   const int numThreads = 26;
   static bool running = true;

   // Statistics.
   static int readerTimeouts = 0;
   static int writerTimeouts = 0;
   static int reads = 0;
   static int writes = 0;

   public static void Main()
   {
      // Start a series of threads to randomly read from and
      // write to the shared resource.
      Thread[] t = new Thread[numThreads];
      for (int i = 0; i < numThreads; i++){
         t[i] = new Thread(new ThreadStart(ThreadProc));
         t[i].Name = new String(Convert.ToChar(i + 65), 1);
         t[i].Start();
         if (i > 10)
            Thread.Sleep(300);
      }

      // Tell the threads to shut down and wait until they all finish.
      running = false;
      for (int i = 0; i < numThreads; i++)
         t[i].Join();

      // Display statistics.
      Console.WriteLine("\n{0} reads, {1} writes, {2} reader time-outs, {3} writer time-outs.",
            reads, writes, readerTimeouts, writerTimeouts);
      Console.Write("Press ENTER to exit... ");
      Console.ReadLine();
   }

   static void ThreadProc()
   {
      Random rnd = new Random();

      // Randomly select a way for the thread to read and write from the shared
      // resource.
      while (running) {
         double action = rnd.NextDouble();
         if (action < .8)
            ReadFromResource(10);
         else if (action < .81)
            ReleaseRestore(rnd, 50);
         else if (action < .90)
            UpgradeDowngrade(rnd, 100);
         else
            WriteToResource(rnd, 100);
      }
   }

   // Request and release a reader lock, and handle time-outs.
   static void ReadFromResource(int timeOut)
   {
      try {
         rwl.AcquireReaderLock(timeOut);
         try {
            // It is safe for this thread to read from the shared resource.
            Display("reads resource value " + resource);
            Interlocked.Increment(ref reads);
         }
         finally {
            // Ensure that the lock is released.
            rwl.ReleaseReaderLock();
         }
      }
      catch (ApplicationException) {
         // The reader lock request timed out.
         Interlocked.Increment(ref readerTimeouts);
      }
   }

   // Request and release the writer lock, and handle time-outs.
   static void WriteToResource(Random rnd, int timeOut)
   {
      try {
         rwl.AcquireWriterLock(timeOut);
         try {
            // It's safe for this thread to access from the shared resource.
            resource = rnd.Next(500);
            Display("writes resource value " + resource);
            Interlocked.Increment(ref writes);
         }
         finally {
            // Ensure that the lock is released.
            rwl.ReleaseWriterLock();
         }
      }
      catch (ApplicationException) {
         // The writer lock request timed out.
         Interlocked.Increment(ref writerTimeouts);
      }
   }

   // Requests a reader lock, upgrades the reader lock to the writer
   // lock, and downgrades it to a reader lock again.
   static void UpgradeDowngrade(Random rnd, int timeOut)
   {
      try {
         rwl.AcquireReaderLock(timeOut);
         try {
            // It's safe for this thread to read from the shared resource.
            Display("reads resource value " + resource);
            Interlocked.Increment(ref reads);

            // To write to the resource, either release the reader lock and
            // request the writer lock, or upgrade the reader lock. Upgrading
            // the reader lock puts the thread in the write queue, behind any
            // other threads that might be waiting for the writer lock.
            try {
               LockCookie lc = rwl.UpgradeToWriterLock(timeOut);
               try {
                  // It's safe for this thread to read or write from the shared resource.
                  resource = rnd.Next(500);
                  Display("writes resource value " + resource);
                  Interlocked.Increment(ref writes);
               }
               finally {
                  // Ensure that the lock is released.
                  rwl.DowngradeFromWriterLock(ref lc);
               }
            }
            catch (ApplicationException) {
               // The upgrade request timed out.
               Interlocked.Increment(ref writerTimeouts);
            }

            // If the lock was downgraded, it's still safe to read from the resource.
            Display("reads resource value " + resource);
            Interlocked.Increment(ref reads);
         }
         finally {
            // Ensure that the lock is released.
            rwl.ReleaseReaderLock();
         }
      }
      catch (ApplicationException) {
         // The reader lock request timed out.
         Interlocked.Increment(ref readerTimeouts);
      }
   }

   // Release all locks and later restores the lock state.
   // Uses sequence numbers to determine whether another thread has
   // obtained a writer lock since this thread last accessed the resource.
   static void ReleaseRestore(Random rnd, int timeOut)
   {
      int lastWriter;

      try {
         rwl.AcquireReaderLock(timeOut);
         try {
            // It's safe for this thread to read from the shared resource,
            // so read and cache the resource value.
            int resourceValue = resource;     // Cache the resource value.
            Display("reads resource value " + resourceValue);
            Interlocked.Increment(ref reads);

            // Save the current writer sequence number.
            lastWriter = rwl.WriterSeqNum;

            // Release the lock and save a cookie so the lock can be restored later.
            LockCookie lc = rwl.ReleaseLock();

            // Wait for a random interval and then restore the previous state of the lock.
            Thread.Sleep(rnd.Next(250));
            rwl.RestoreLock(ref lc);

            // Check whether other threads obtained the writer lock in the interval.
            // If not, then the cached value of the resource is still valid.
            if (rwl.AnyWritersSince(lastWriter)) {
               resourceValue = resource;
               Interlocked.Increment(ref reads);
               Display("resource has changed " + resourceValue);
            }
            else {
               Display("resource has not changed " + resourceValue);
            }
         }
         finally {
            // Ensure that the lock is released.
            rwl.ReleaseReaderLock();
         }
      }
      catch (ApplicationException) {
         // The reader lock request timed out.
         Interlocked.Increment(ref readerTimeouts);
      }
   }

   // Helper method briefly displays the most recent thread action.
   static void Display(string msg)
   {
      Console.Write("Thread {0} {1}.       \r", Thread.CurrentThread.Name, msg);
   }
}
' The complete code is located in the ReaderWriterLock class topic.
Imports System.Threading

Public Module Example
   Private rwl As New ReaderWriterLock()
   ' Define the shared resource protected by the ReaderWriterLock.
   Private resource As Integer = 0

   Const numThreads As Integer = 26
   Private running As Boolean = True
   
   ' Statistics.
   Private readerTimeouts As Integer = 0
   Private writerTimeouts As Integer = 0
   Private reads As Integer = 0
   Private writes As Integer = 0
  
   Public Sub Main()
      ' Start a series of threads to randomly read from and
      ' write to the shared resource.
      Dim t(numThreads - 1) As Thread
      Dim i As Integer
      For i = 0 To numThreads - 1
         t(i) = New Thread(New ThreadStart(AddressOf ThreadProc))
         t(i).Name = Chr(i + 65)
         t(i).Start()
         If i > 10 Then
            Thread.Sleep(300)
         End If
      Next

      ' Tell the threads to shut down and wait until they all finish.
      running = False
      For i = 0 To numThreads - 1
         t(i).Join()
      Next
      
      ' Display statistics.
      Console.WriteLine(vbCrLf & "{0} reads, {1} writes, {2} reader time-outs, {3} writer time-outs.",
                        reads, writes, readerTimeouts, writerTimeouts)
      Console.Write("Press ENTER to exit... ")
      Console.ReadLine()
   End Sub

   Sub ThreadProc()
      Dim rnd As New Random

      ' Randomly select a way for the thread to read and write from the shared
      ' resource.
      While running
         Dim action As Double = rnd.NextDouble()
         If action < 0.8 Then
            ReadFromResource(10)
         ElseIf action < 0.81 Then
            ReleaseRestore(rnd, 50)
         ElseIf action < 0.9 Then
            UpgradeDowngrade(rnd, 100)
         Else
            WriteToResource(rnd, 100)
         End If
      End While
   End Sub
    
   ' Request and release a reader lock, and handle time-outs.
   Sub ReadFromResource(timeOut As Integer)
      Try
         rwl.AcquireReaderLock(timeOut)
         Try
            ' It's safe for this thread to read from the shared resource.
            Display("reads resource value " & resource)
            Interlocked.Increment(reads)
         Finally
            ' Ensure that the lock is released.
            rwl.ReleaseReaderLock()
         End Try
      Catch ex As ApplicationException
         ' The reader lock request timed out.
         Interlocked.Increment(readerTimeouts)
      End Try
   End Sub

   ' Request and release the writer lock, and handle time-outs.
   Sub WriteToResource(rnd As Random, timeOut As Integer)
      Try
         rwl.AcquireWriterLock(timeOut)
         Try
            ' It's safe for this thread to read or write from the shared resource.
            resource = rnd.Next(500)
            Display("writes resource value " & resource)
            Interlocked.Increment(writes)
         Finally
            ' Ensure that the lock is released.
            rwl.ReleaseWriterLock()
         End Try
      Catch ex As ApplicationException
         ' The writer lock request timed out.
         Interlocked.Increment(writerTimeouts)
      End Try
   End Sub

   ' Requests a reader lock, upgrades the reader lock to the writer
   ' lock, and downgrades it to a reader lock again.
   Sub UpgradeDowngrade(rnd As Random, timeOut As Integer)
      Try
         rwl.AcquireReaderLock(timeOut)
         Try
            ' It's safe for this thread to read from the shared resource.
            Display("reads resource value " & resource)
            Interlocked.Increment(reads)
            
            ' To write to the resource, either release the reader lock and
            ' request the writer lock, or upgrade the reader lock. Upgrading
            ' the reader lock puts the thread in the write queue, behind any
            ' other threads that might be waiting for the writer lock.
            Try
               Dim lc As LockCookie = rwl.UpgradeToWriterLock(timeOut)
               Try
                  ' It's safe for this thread to read or write from the shared resource.
                  resource = rnd.Next(500)
                  Display("writes resource value " & resource)
                  Interlocked.Increment(writes)
               Finally
                  ' Ensure that the lock is released.
                  rwl.DowngradeFromWriterLock(lc)
               End Try
            Catch ex As ApplicationException
               ' The upgrade request timed out.
               Interlocked.Increment(writerTimeouts)
            End Try
            
            ' If the lock was downgraded, it's still safe to read from the resource.
            Display("reads resource value " & resource)
            Interlocked.Increment(reads)
         Finally
            ' Ensure that the lock is released.
            rwl.ReleaseReaderLock()
         End Try
      Catch ex As ApplicationException
         ' The reader lock request timed out.
         Interlocked.Increment(readerTimeouts)
      End Try
   End Sub

   ' Release all locks and later restores the lock state.
   ' Uses sequence numbers to determine whether another thread has
   ' obtained a writer lock since this thread last accessed the resource.
   Sub ReleaseRestore(rnd As Random ,timeOut As Integer)
      Dim lastWriter As Integer
      
      Try
         rwl.AcquireReaderLock(timeOut)
         Try
            ' It's safe for this thread to read from the shared resource,
            ' so read and cache the resource value.
            Dim resourceValue As Integer = resource
            Display("reads resource value " & resourceValue)
            Interlocked.Increment(reads)
            
            ' Save the current writer sequence number.
            lastWriter = rwl.WriterSeqNum
            
            ' Release the lock and save a cookie so the lock can be restored later.
            Dim lc As LockCookie = rwl.ReleaseLock()
            
            ' Wait for a random interval and then restore the previous state of the lock.
            Thread.Sleep(rnd.Next(250))
            rwl.RestoreLock(lc)
           
            ' Check whether other threads obtained the writer lock in the interval.
            ' If not, then the cached value of the resource is still valid.
            If rwl.AnyWritersSince(lastWriter) Then
               resourceValue = resource
               Interlocked.Increment(reads)
               Display("resource has changed " & resourceValue)
            Else
               Display("resource has not changed " & resourceValue)
            End If
         Finally
            ' Ensure that the lock is released.
            rwl.ReleaseReaderLock()
         End Try
      Catch ex As ApplicationException
         ' The reader lock request timed out.
         Interlocked.Increment(readerTimeouts)
      End Try
   End Sub

   ' Helper method briefly displays the most recent thread action.
   Sub Display(msg As String)
      Console.Write("Thread {0} {1}.       " & vbCr, Thread.CurrentThread.Name, msg)
   End Sub
End Module

설명

중요

이 .NET Framework에는 및의 두 가지 판독기 기록기 잠금이 있습니다 ReaderWriterLockSlim ReaderWriterLock .The .NET Framework has two reader-writer locks, ReaderWriterLockSlim and ReaderWriterLock. ReaderWriterLockSlim은 모든 새 개발에 권장됩니다.ReaderWriterLockSlim is recommended for all new development. ReaderWriterLockSlimReaderWriterLock과 비슷하지만 재귀 및 잠금 상태 업그레이드/다운그레이드에 대한 간소화된 규칙을 포함합니다.ReaderWriterLockSlim is similar to ReaderWriterLock, but it has simplified rules for recursion and for upgrading and downgrading lock state. ReaderWriterLockSlim은 교착 상태가 발생할 수 있는 많은 경우를 방지합니다.ReaderWriterLockSlim avoids many cases of potential deadlock. 또한 ReaderWriterLockSlim의 성능이 ReaderWriterLock보다 훨씬 더 놓습니다.In addition, the performance of ReaderWriterLockSlim is significantly better than ReaderWriterLock.

ReaderWriterLock 는 리소스에 대 한 액세스를 동기화 하는 데 사용 됩니다.ReaderWriterLock is used to synchronize access to a resource. 지정 된 시간에 여러 스레드에 대해 동시 읽기 액세스를 허용 하거나 단일 스레드에 대 한 쓰기 액세스를 허용 합니다.At any given time, it allows either concurrent read access for multiple threads, or write access for a single thread. 리소스가 자주 변경 되지 않는 상황에서는 ReaderWriterLock 와 같은 간단한 일회성 잠금 보다 향상 된 처리량을 제공 Monitor 합니다.In a situation where a resource is changed infrequently, a ReaderWriterLock provides better throughput than a simple one-at-a-time lock, such as Monitor.

ReaderWriterLock 대부분의 액세스는 읽기이 고 쓰기는 드물게 발생 하며 쓰기는 짧은 기간에 가장 잘 작동 합니다.ReaderWriterLock works best where most accesses are reads, while writes are infrequent and of short duration. 여러 판독기가 단일 작성기를 대체 하므로 판독기와 기록기가 장기간 차단 되지 않습니다.Multiple readers alternate with single writers, so that neither readers nor writers are blocked for long periods.

참고

긴 기간 동안 판독기 잠금 또는 작성자 잠금을 보유 하면 다른 스레드가 결핍 됩니다.Holding reader locks or writer locks for long periods will starve other threads. 최상의 성능을 위해 쓰기의 기간을 최소화 하도록 애플리케이션을 재구성 하는 것이 좋습니다.For best performance, consider restructuring your application to minimize the duration of writes.

스레드는 판독기 잠금이나 작성기 잠금을 보유할 수 있지만 동시에 둘 다가 될 수는 없습니다.A thread can hold a reader lock or a writer lock, but not both at the same time. 작성기 잠금을 획득 하기 위해 판독기 잠금을 해제 하는 대신 및를 사용할 수 있습니다 UpgradeToWriterLock DowngradeFromWriterLock .Instead of releasing a reader lock in order to acquire the writer lock, you can use UpgradeToWriterLock and DowngradeFromWriterLock.

재귀적 잠금 요청은 잠금에 대 한 잠금 횟수를 늘립니다.Recursive lock requests increase the lock count on a lock.

판독기와 작성기는 별도로 큐에 저장 됩니다.Readers and writers are queued separately. 스레드가 작성기 잠금을 해제 하면 해당 순간에 판독기 큐에서 대기 중인 모든 스레드에 판독기 잠금이 부여 됩니다. 이러한 모든 판독기 잠금이 해제 되 면 기록기 큐를 대기 하는 다음 스레드 (있는 경우)에 작성기 잠금이 부여 됩니다.When a thread releases the writer lock, all threads waiting in the reader queue at that instant are granted reader locks; when all of those reader locks have been released, the next thread waiting in the writer queue, if any, is granted the writer lock, and so on. 즉, ReaderWriterLock 판독기 컬렉션과 작성기 중 하나가 교대로 반복 됩니다.In other words, ReaderWriterLock alternates between a collection of readers, and one writer.

기록기 큐의 스레드가 활성 판독기 잠금이 해제 될 때까지 대기 하는 동안 새 판독기 잠금을 요청 하는 스레드는 판독기 큐에 누적 됩니다.While a thread in the writer queue is waiting for active reader locks to be released, threads requesting new reader locks accumulate in the reader queue. 기존 판독기 잠금 소유자와 동시 액세스를 공유할 수 있는 경우에도 해당 요청은 부여 되지 않습니다. 이렇게 하면 판독기가 무한 차단을 으로부터 작성기를 보호 하는 데 도움이 됩니다.Their requests are not granted, even though they could share concurrent access with existing reader-lock holders; this helps protect writers against indefinite blockage by readers.

에서 잠금 획득에 대 한 대부분의 메서드는 ReaderWriterLock 제한 시간 값을 허용 합니다.Most methods for acquiring locks on a ReaderWriterLock accept time-out values. 애플리케이션에서 교착 상태 방지 하려면 제한 시간을 사용 합니다.Use time-outs to avoid deadlocks in your application. 예를 들어 스레드가 한 리소스에 대 한 작성기 잠금을 획득 한 다음 두 번째 리소스에 대해 판독기 잠금을 요청할 수 있습니다. 그 동안 다른 스레드가 두 번째 리소스에 대해 작성기 잠금을 획득 하 고 첫 번째 리소스에서 판독기 잠금을 요청할 수 있습니다.For example, a thread might acquire the writer lock on one resource and then request a reader lock on a second resource; in the meantime, another thread might acquire the writer lock on the second resource, and request a reader lock on the first. 제한 시간을 사용 하지 않는 한 스레드 교착 상태가 발생 합니다.Unless time-outs are used, the threads deadlock.

제한 시간 간격이 만료 되 고 잠금 요청이 부여 되지 않은 경우 메서드는을 throw 하 여 호출 스레드에 제어를 반환 합니다 ApplicationException .If the time-out interval expires and the lock request has not been granted, the method returns control to the calling thread by throwing an ApplicationException. 스레드는이 예외를 catch 하 고 다음에 수행할 작업을 결정할 수 있습니다.A thread can catch this exception and determine what action to take next.

제한 시간은 밀리초 단위로 표시 됩니다.Time-outs are expressed in milliseconds. 을 사용 하 여 System.TimeSpan 제한 시간을 지정 하는 경우 사용 되는 값은이 나타내는 전체 밀리초의 총 수입니다 TimeSpan .If you use a System.TimeSpan to specify the time-out, the value used is the total number of whole milliseconds represented by the TimeSpan. 다음 표에서는 유효한 제한 시간 값 (밀리초)을 보여 줍니다.The following table shows the valid time-out values in milliseconds.

Value 설명Description
-1-1 스레드는 걸리는 시간에 관계 없이 잠금을 획득할 때까지 대기 합니다.The thread waits until the lock is acquired, regardless of how long it takes. 정수 제한 시간을 지정 하는 메서드의 경우 상수를 Infinite 사용할 수 있습니다.For methods that specify integer time-outs, the constant Infinite can be used.
00 스레드가 잠금을 획득 하기 위해 대기 하지 않습니다.The thread does not wait to acquire the lock. 잠금을 즉시 가져올 수 없는 경우이 메서드는를 반환 합니다.If the lock cannot be acquired immediately, the method returns.
>0>0 대기하는 밀리초 수입니다.The number of milliseconds to wait.

-1은 제외 하 고 음수 시간 제한 값은 허용 되지 않습니다.With the exception of -1, negative time-out values are not allowed. -1 이외의 음의 정수를 지정 하는 경우 시간 제한 값 0이 대신 사용 됩니다.If you specify a negative integer other than -1, a time-out value of zero is used instead. 즉, 잠금을 즉시 가져올 수 없는 경우 메서드가 대기 하지 않고 반환 됩니다. TimeSpan -1 이외의 음수 시간 (밀리초)을 나타내는을 지정 하면 ArgumentOutOfRangeException 이 throw 됩니다.(That is, the method returns without waiting, if the lock cannot be acquired immediately.) If you specify a TimeSpan that represents a negative number of milliseconds other than -1, ArgumentOutOfRangeException is thrown.

생성자

ReaderWriterLock()

ReaderWriterLock 클래스의 새 인스턴스를 초기화합니다.Initializes a new instance of the ReaderWriterLock class.

속성

IsReaderLockHeld

현재 스레드에 판독기 잠금이 있는지 여부를 나타내는 값을 가져옵니다.Gets a value indicating whether the current thread holds a reader lock.

IsWriterLockHeld

현재 스레드에 작성기 잠금이 있는지 여부를 나타내는 값을 가져옵니다.Gets a value indicating whether the current thread holds the writer lock.

WriterSeqNum

현재 시퀀스 번호를 가져옵니다.Gets the current sequence number.

메서드

AcquireReaderLock(Int32)

제한 시간에 Int32 값을 사용하여 판독기 잠금을 가져옵니다.Acquires a reader lock, using an Int32 value for the time-out.

AcquireReaderLock(TimeSpan)

제한 시간에 TimeSpan 값을 사용하여 판독기 잠금을 가져옵니다.Acquires a reader lock, using a TimeSpan value for the time-out.

AcquireWriterLock(Int32)

제한 시간에 Int32 값을 사용하여 작성기 잠금을 가져옵니다.Acquires the writer lock, using an Int32 value for the time-out.

AcquireWriterLock(TimeSpan)

제한 시간에 TimeSpan 값을 사용하여 작성기 잠금을 가져옵니다.Acquires the writer lock, using a TimeSpan value for the time-out.

AnyWritersSince(Int32)

시퀀스 번호를 가져온 다음 임의의 스레드에 작성기 잠금이 부여되었는지 여부를 나타냅니다.Indicates whether the writer lock has been granted to any thread since the sequence number was obtained.

DowngradeFromWriterLock(LockCookie)

UpgradeToWriterLock(Int32)을 호출하기 전에 스레드의 잠금 상태를 이전 상태로 복원합니다.Restores the lock status of the thread to what it was before UpgradeToWriterLock(Int32) was called.

Equals(Object)

지정된 개체가 현재 개체와 같은지 확인합니다.Determines whether the specified object is equal to the current object.

(다음에서 상속됨 Object)
Finalize()

가비지 컬렉션기에서 ReaderWriterLock 개체를 회수할 때 리소스가 해제되고 다른 정리 작업이 수행되도록 합니다.Ensures that resources are freed and other cleanup operations are performed when the garbage collector reclaims the ReaderWriterLock object.

GetHashCode()

기본 해시 함수로 작동합니다.Serves as the default hash function.

(다음에서 상속됨 Object)
GetType()

현재 인스턴스의 Type을 가져옵니다.Gets the Type of the current instance.

(다음에서 상속됨 Object)
MemberwiseClone()

현재 Object의 단순 복사본을 만듭니다.Creates a shallow copy of the current Object.

(다음에서 상속됨 Object)
ReleaseLock()

스레드에서 잠금을 가져온 횟수에 관계 없이 잠금을 해제합니다.Releases the lock, regardless of the number of times the thread acquired the lock.

ReleaseReaderLock()

잠금 횟수를 줄입니다.Decrements the lock count.

ReleaseWriterLock()

작성기 잠금의 잠금 횟수를 줄입니다.Decrements the lock count on the writer lock.

RestoreLock(LockCookie)

ReleaseLock()을 호출하기 전에 스레드의 이전 잠금 상태를 복구합니다.Restores the lock status of the thread to what it was before calling ReleaseLock().

ToString()

현재 개체를 나타내는 문자열을 반환합니다.Returns a string that represents the current object.

(다음에서 상속됨 Object)
UpgradeToWriterLock(Int32)

제한 시간에 Int32 값을 사용하여 판독기 잠금을 작성기 잠금으로 업그레이드합니다.Upgrades a reader lock to the writer lock, using an Int32 value for the time-out.

UpgradeToWriterLock(TimeSpan)

제한 시간에 TimeSpan 값을 사용하여 판독기 잠금을 작성기 잠금으로 업그레이드합니다.Upgrades a reader lock to the writer lock, using a TimeSpan value for the time-out.

적용 대상

스레드 보안

이 형식은 스레드로부터 안전합니다.This type is thread safe.