[Mono-bugs] [Bug 395069] New: Console.Write() isn't thread safe

bugzilla_noreply at novell.com bugzilla_noreply at novell.com
Wed May 28 09:32:33 EDT 2008


https://bugzilla.novell.com/show_bug.cgi?id=395069


           Summary: Console.Write() isn't thread safe
           Product: Mono: Runtime
           Version: SVN
          Platform: x86-64
        OS/Version: openSUSE 11.0
            Status: NEW
          Severity: Normal
          Priority: P5 - None
         Component: io-layer
        AssignedTo: dick at novell.com
        ReportedBy: jpryor at novell.com
         QAContact: mono-bugs at lists.ximian.com
          Found By: ---


Console.Write() doesn't appear to be thread safe.

Example 1:

  using System;
  using System.Threading;

  class Test {
    public static void Main ()
    {
      Thread[] threads = new Thread[]{
        new Thread ( () => { WriteMessage ("Thread 1"); } ),
        new Thread ( () => { WriteMessage ("Thread 2"); } ),
      };
      foreach (var t in threads)
        t.Start ();
      foreach (var t in threads)
        t.Join ();
    }

    static void WriteMessage (string who)
    {
      Console.Write ("Hello from " + who + "!\n");
    }
  }

Compile: gmcs ls.cs

Run several times:

  $ mono ls.exe 
  Hello from Thread 1!
  Hello from Thread 2!
  Hello from Thread 1!
  Hello from Thread 2!
  $ mono ls.exe 
  Hello from Thread 2!
  Hello from Thread 1!
  $ mono ls.exe 
  Hello from Thread 2!
  Hello from Thread 1!
  Hello from Thread 2!


Only two Console.Write()s should ever be executed.  How can there be 4 (as in
the first example), or 3 (as in the last)?

If we try a closely related example (only WriteMessage() differs):

  using System;
  using System.Threading;

  class Test {
    public static void Main ()
    {
      Thread[] threads = new Thread[]{
        new Thread ( () => { WriteMessage ("Thread 1"); } ),
        new Thread ( () => { WriteMessage ("Thread 2"); } ),
      };
      foreach (var t in threads)
        t.Start ();
      foreach (var t in threads)
        t.Join ();
    }

    static void WriteMessage (string who)
    {
      Console.Write ("Hello from ");
      Console.Write (who);
      Console.Write ("!\n");
    }
  }

This WriteMessage() behavior isn't fully "thread-safe".  That said, the
individual string writes _should_ be, so the output should contain two "Hello
from " sequences (uninterrupted), two "!\n" sequences, and one "Thread 1" and
one "Thread 2" sequence.

Compile and run several times, and instead:

  $ mono ls.exe 
  Hello from Hello from Hello from Hello from Thread 1Thread 2!
  Thread 2!

*4* "Hello from " strings, and *2* "Thread 2" strings.  I cannot fathom how
this happens.

Or worse:

  $ mono ls.exe 
  Hello from Hello from Thread 1!
  !
  read 1om Hello from Thread 2!

*3* "Hello from " sequences, and apparently the output buffer was reused during
the write(2) call, as "1" is separate from "Thread" on the 3rd output line.

This is not the behavior I would expect.  Interleaving of the individual
Console.Write() calls, yes, but not _extra_ or _corrupted_ output.


-- 
Configure bugmail: https://bugzilla.novell.com/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.


More information about the mono-bugs mailing list