thread synchronization

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Daniel

    #1

    thread synchronization

    i have an array that i want all threads to be able to READ from
    concurrently, however, at times i want to UPDATE the array. at which point i
    want all threads that use it to block when they try to read from the array.
    currently i do this by wrapping ALL READ AND WRITE access to the array in a
    lock("foobar"){ } this prevernts threads from reading from the array while it
    is being written to however it ALSO keeps more then one thread from reading
    the array at a time. how to solve this so that multiple threads can read the
    array at the same time but whent he array is being updated all threads that
    want to read from it block until it updates, and so that the code to update
    the array blocks until no thread is reading from the array before it starts
    to update it?


  • Michael McCarthy

    #2
    Re: thread synchronization

    Use a Mutex object,

    You can use a mutex object to protect a shared resource from
    simultaneous access by multiple threads or processes. The state of a
    mutex object is either set to signaled, when it is not owned by any
    thread, or nonsignaled, when it is owned. Only one thread at a time can
    own a mutex object. For example, to prevent two threads from writing to
    shared memory at the same time, each thread waits for ownership of a
    mutex object before executing the code that accesses the memory. After
    writing to the shared memory, the thread releases the mutex object.

    This example demonstrates how to use the classes Mutex, AutoResetEvent,
    and WaitHandle in processing threads. It also demonstrates the methods
    used in processing the mutex object.

    // Mutex.cs
    // Mutex object example
    using System;
    using System.Threadin g;

    public class MutexSample
    {
    static Mutex gM1;
    static Mutex gM2;
    const int ITERS = 100;
    static AutoResetEvent Event1 = new AutoResetEvent( false);
    static AutoResetEvent Event2 = new AutoResetEvent( false);
    static AutoResetEvent Event3 = new AutoResetEvent( false);
    static AutoResetEvent Event4 = new AutoResetEvent( false);

    public static void Main(String[] args)
    {
    Console.WriteLi ne("Mutex Sample ...");
    // Create Mutex initialOwned, with name of "MyMutex".
    gM1 = new Mutex(true,"MyM utex");
    // Create Mutex initialOwned, with no name.
    gM2 = new Mutex(true);
    Console.WriteLi ne(" - Main Owns gM1 and gM2");

    AutoResetEvent[] evs = new AutoResetEvent[4];
    evs[0] = Event1; // Event for t1
    evs[1] = Event2; // Event for t2
    evs[2] = Event3; // Event for t3
    evs[3] = Event4; // Event for t4

    MutexSample tm = new MutexSample( );
    Thread t1 = new Thread(new ThreadStart(tm. t1Start));
    Thread t2 = new Thread(new ThreadStart(tm. t2Start));
    Thread t3 = new Thread(new ThreadStart(tm. t3Start));
    Thread t4 = new Thread(new ThreadStart(tm. t4Start));
    t1.Start( ); // Does Mutex.WaitAll(M utex[] of gM1 and gM2)
    t2.Start( ); // Does Mutex.WaitOne(M utex gM1)
    t3.Start( ); // Does Mutex.WaitAny(M utex[] of gM1 and gM2)
    t4.Start( ); // Does Mutex.WaitOne(M utex gM2)

    Thread.Sleep(20 00);
    Console.WriteLi ne(" - Main releases gM1");
    gM1.ReleaseMute x( ); // t2 and t3 will end and signal

    Thread.Sleep(10 00);
    Console.WriteLi ne(" - Main releases gM2");
    gM2.ReleaseMute x( ); // t1 and t4 will end and signal

    // Waiting until all four threads signal that they are done.
    WaitHandle.Wait All(evs);
    Console.WriteLi ne("... Mutex Sample");
    }

    public void t1Start( )
    {
    Console.WriteLi ne("t1Start started, Mutex.WaitAll(M utex[])");
    Mutex[] gMs = new Mutex[2];
    gMs[0] = gM1; // Create and load an array of Mutex for WaitAll call
    gMs[1] = gM2;
    Mutex.WaitAll(g Ms); // Waits until both gM1 and gM2 are released
    Thread.Sleep(20 00);
    Console.WriteLi ne("t1Start finished, Mutex.WaitAll(M utex[])
    satisfied");
    Event1.Set( ); // AutoResetEvent. Set() flagging method is done
    }

    public void t2Start( )
    {
    Console.WriteLi ne("t2Start started, gM1.WaitOne( )");
    gM1.WaitOne( ); // Waits until Mutex gM1 is released
    Console.WriteLi ne("t2Start finished, gM1.WaitOne( ) satisfied");
    Event2.Set( ); // AutoResetEvent. Set() flagging method is done
    }

    public void t3Start( )
    {
    Console.WriteLi ne("t3Start started, Mutex.WaitAny(M utex[])");
    Mutex[] gMs = new Mutex[2];
    gMs[0] = gM1; // Create and load an array of Mutex for WaitAny call
    gMs[1] = gM2;
    Mutex.WaitAny(g Ms); // Waits until either Mutex is released
    Console.WriteLi ne("t3Start finished, Mutex.WaitAny(M utex[])");
    Event3.Set( ); // AutoResetEvent. Set() flagging method is done
    }

    public void t4Start( )
    {
    Console.WriteLi ne("t4Start started, gM2.WaitOne( )");
    gM2.WaitOne( ); // Waits until Mutex gM2 is released
    Console.WriteLi ne("t4Start finished, gM2.WaitOne( )");
    Event4.Set( ); // AutoResetEvent. Set() flagging method is done
    }
    }

    Sample Output

    Mutex Sample ...
    - Main Owns gM1 and gM2
    t1Start started, Mutex.WaitAll(M utex[])
    t2Start started, gM1.WaitOne( )
    t3Start started, Mutex.WaitAny(M utex[])
    t4Start started, gM2.WaitOne( )
    - Main releases gM1
    t2Start finished, gM1.WaitOne( ) satisfied
    t3Start finished, Mutex.WaitAny(M utex[])
    - Main releases gM2
    t1Start finished, Mutex.WaitAll(M utex[]) satisfied
    t4Start finished, gM2.WaitOne( )
    .... Mutex Sample

    ~~~
    Daniel wrote:[color=blue]
    > i have an array that i want all threads to be able to READ from
    > concurrently, however, at times i want to UPDATE the array. at which point i
    > want all threads that use it to block when they try to read from the array.
    > currently i do this by wrapping ALL READ AND WRITE access to the array in a
    > lock("foobar"){ } this prevernts threads from reading from the array while it
    > is being written to however it ALSO keeps more then one thread from reading
    > the array at a time. how to solve this so that multiple threads can read the
    > array at the same time but whent he array is being updated all threads that
    > want to read from it block until it updates, and so that the code to update
    > the array blocks until no thread is reading from the array before it starts
    > to update it?
    >
    >[/color]

    Comment

    • Michael McCarthy

      #3
      Re: thread synchronization

      Use a Mutex object,

      You can use a mutex object to protect a shared resource from
      simultaneous access by multiple threads or processes. The state of a
      mutex object is either set to signaled, when it is not owned by any
      thread, or nonsignaled, when it is owned. Only one thread at a time can
      own a mutex object. For example, to prevent two threads from writing to
      shared memory at the same time, each thread waits for ownership of a
      mutex object before executing the code that accesses the memory. After
      writing to the shared memory, the thread releases the mutex object.

      This example demonstrates how to use the classes Mutex, AutoResetEvent,
      and WaitHandle in processing threads. It also demonstrates the methods
      used in processing the mutex object.

      // Mutex.cs
      // Mutex object example
      using System;
      using System.Threadin g;

      public class MutexSample
      {
      static Mutex gM1;
      static Mutex gM2;
      const int ITERS = 100;
      static AutoResetEvent Event1 = new AutoResetEvent( false);
      static AutoResetEvent Event2 = new AutoResetEvent( false);
      static AutoResetEvent Event3 = new AutoResetEvent( false);
      static AutoResetEvent Event4 = new AutoResetEvent( false);

      public static void Main(String[] args)
      {
      Console.WriteLi ne("Mutex Sample ...");
      // Create Mutex initialOwned, with name of "MyMutex".
      gM1 = new Mutex(true,"MyM utex");
      // Create Mutex initialOwned, with no name.
      gM2 = new Mutex(true);
      Console.WriteLi ne(" - Main Owns gM1 and gM2");

      AutoResetEvent[] evs = new AutoResetEvent[4];
      evs[0] = Event1; // Event for t1
      evs[1] = Event2; // Event for t2
      evs[2] = Event3; // Event for t3
      evs[3] = Event4; // Event for t4

      MutexSample tm = new MutexSample( );
      Thread t1 = new Thread(new ThreadStart(tm. t1Start));
      Thread t2 = new Thread(new ThreadStart(tm. t2Start));
      Thread t3 = new Thread(new ThreadStart(tm. t3Start));
      Thread t4 = new Thread(new ThreadStart(tm. t4Start));
      t1.Start( ); // Does Mutex.WaitAll(M utex[] of gM1 and gM2)
      t2.Start( ); // Does Mutex.WaitOne(M utex gM1)
      t3.Start( ); // Does Mutex.WaitAny(M utex[] of gM1 and gM2)
      t4.Start( ); // Does Mutex.WaitOne(M utex gM2)

      Thread.Sleep(20 00);
      Console.WriteLi ne(" - Main releases gM1");
      gM1.ReleaseMute x( ); // t2 and t3 will end and signal

      Thread.Sleep(10 00);
      Console.WriteLi ne(" - Main releases gM2");
      gM2.ReleaseMute x( ); // t1 and t4 will end and signal

      // Waiting until all four threads signal that they are done.
      WaitHandle.Wait All(evs);
      Console.WriteLi ne("... Mutex Sample");
      }

      public void t1Start( )
      {
      Console.WriteLi ne("t1Start started, Mutex.WaitAll(M utex[])");
      Mutex[] gMs = new Mutex[2];
      gMs[0] = gM1; // Create and load an array of Mutex for WaitAll call
      gMs[1] = gM2;
      Mutex.WaitAll(g Ms); // Waits until both gM1 and gM2 are released
      Thread.Sleep(20 00);
      Console.WriteLi ne("t1Start finished, Mutex.WaitAll(M utex[])
      satisfied");
      Event1.Set( ); // AutoResetEvent. Set() flagging method is done
      }

      public void t2Start( )
      {
      Console.WriteLi ne("t2Start started, gM1.WaitOne( )");
      gM1.WaitOne( ); // Waits until Mutex gM1 is released
      Console.WriteLi ne("t2Start finished, gM1.WaitOne( ) satisfied");
      Event2.Set( ); // AutoResetEvent. Set() flagging method is done
      }

      public void t3Start( )
      {
      Console.WriteLi ne("t3Start started, Mutex.WaitAny(M utex[])");
      Mutex[] gMs = new Mutex[2];
      gMs[0] = gM1; // Create and load an array of Mutex for WaitAny call
      gMs[1] = gM2;
      Mutex.WaitAny(g Ms); // Waits until either Mutex is released
      Console.WriteLi ne("t3Start finished, Mutex.WaitAny(M utex[])");
      Event3.Set( ); // AutoResetEvent. Set() flagging method is done
      }

      public void t4Start( )
      {
      Console.WriteLi ne("t4Start started, gM2.WaitOne( )");
      gM2.WaitOne( ); // Waits until Mutex gM2 is released
      Console.WriteLi ne("t4Start finished, gM2.WaitOne( )");
      Event4.Set( ); // AutoResetEvent. Set() flagging method is done
      }
      }

      Sample Output

      Mutex Sample ...
      - Main Owns gM1 and gM2
      t1Start started, Mutex.WaitAll(M utex[])
      t2Start started, gM1.WaitOne( )
      t3Start started, Mutex.WaitAny(M utex[])
      t4Start started, gM2.WaitOne( )
      - Main releases gM1
      t2Start finished, gM1.WaitOne( ) satisfied
      t3Start finished, Mutex.WaitAny(M utex[])
      - Main releases gM2
      t1Start finished, Mutex.WaitAll(M utex[]) satisfied
      t4Start finished, gM2.WaitOne( )
      .... Mutex Sample

      ~~~
      Daniel wrote:[color=blue]
      > i have an array that i want all threads to be able to READ from
      > concurrently, however, at times i want to UPDATE the array. at which point i
      > want all threads that use it to block when they try to read from the array.
      > currently i do this by wrapping ALL READ AND WRITE access to the array in a
      > lock("foobar"){ } this prevernts threads from reading from the array while it
      > is being written to however it ALSO keeps more then one thread from reading
      > the array at a time. how to solve this so that multiple threads can read the
      > array at the same time but whent he array is being updated all threads that
      > want to read from it block until it updates, and so that the code to update
      > the array blocks until no thread is reading from the array before it starts
      > to update it?
      >
      >[/color]

      Comment

      • Jon Skeet [C# MVP]

        #4
        Re: thread synchronization

        Daniel <softwareengine er98037@yahoo.c om> wrote:[color=blue]
        > i have an array that i want all threads to be able to READ from
        > concurrently, however, at times i want to UPDATE the array. at which point i
        > want all threads that use it to block when they try to read from the array.
        > currently i do this by wrapping ALL READ AND WRITE access to the array in a
        > lock("foobar"){ } this prevernts threads from reading from the array while it
        > is being written to however it ALSO keeps more then one thread from reading
        > the array at a time. how to solve this so that multiple threads can read the
        > array at the same time but whent he array is being updated all threads that
        > want to read from it block until it updates, and so that the code to update
        > the array blocks until no thread is reading from the array before it starts
        > to update it?[/color]

        Please see ReaderWriterLoc k, as I posted in answer to your identical
        question on another group.

        --
        Jon Skeet - <skeet@pobox.co m>
        Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.

        If replying to the group, please do not mail me too

        Comment

        • Jon Skeet [C# MVP]

          #5
          Re: thread synchronization

          Daniel <softwareengine er98037@yahoo.c om> wrote:[color=blue]
          > i have an array that i want all threads to be able to READ from
          > concurrently, however, at times i want to UPDATE the array. at which point i
          > want all threads that use it to block when they try to read from the array.
          > currently i do this by wrapping ALL READ AND WRITE access to the array in a
          > lock("foobar"){ } this prevernts threads from reading from the array while it
          > is being written to however it ALSO keeps more then one thread from reading
          > the array at a time. how to solve this so that multiple threads can read the
          > array at the same time but whent he array is being updated all threads that
          > want to read from it block until it updates, and so that the code to update
          > the array blocks until no thread is reading from the array before it starts
          > to update it?[/color]

          Please see ReaderWriterLoc k, as I posted in answer to your identical
          question on another group.

          --
          Jon Skeet - <skeet@pobox.co m>
          Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.

          If replying to the group, please do not mail me too

          Comment

          • Jon Skeet [C# MVP]

            #6
            Re: thread synchronization

            Michael McCarthy <jux@diffjuz.co m> wrote:[color=blue]
            > Use a Mutex object,[/color]

            Eek no. Mutex is (in this case) equivalent to using Monitor.Enter/Exit
            (aka the lock operator in C#) i.e. exclusive locking - except it's
            slower than using Monitor.Enter/Exit.

            That's not suitable here for exactly the reasons given in the original
            post - shared access is required for reading. ReaderWriterLoc k is
            exactly what's wanted here.

            I would strongly discourage the use of Mutex unless a cross-process
            synchronization mechanism is required, or unless you need the
            WaitAny/WaitAll functionality.

            --
            Jon Skeet - <skeet@pobox.co m>
            Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.

            If replying to the group, please do not mail me too

            Comment

            • Jon Skeet [C# MVP]

              #7
              Re: thread synchronization

              Michael McCarthy <jux@diffjuz.co m> wrote:[color=blue]
              > Use a Mutex object,[/color]

              Eek no. Mutex is (in this case) equivalent to using Monitor.Enter/Exit
              (aka the lock operator in C#) i.e. exclusive locking - except it's
              slower than using Monitor.Enter/Exit.

              That's not suitable here for exactly the reasons given in the original
              post - shared access is required for reading. ReaderWriterLoc k is
              exactly what's wanted here.

              I would strongly discourage the use of Mutex unless a cross-process
              synchronization mechanism is required, or unless you need the
              WaitAny/WaitAll functionality.

              --
              Jon Skeet - <skeet@pobox.co m>
              Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.

              If replying to the group, please do not mail me too

              Comment

              Working...