Threadsafe value types

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

    Threadsafe value types

    If a value type is immutable, I guess it's threadsafe to read it? But not
    threadsafe to assign a new value to it (can any value type be truely
    immutable? Isn't assigning a totally new value to it, like doing an
    modification, when no references are involved? I don't know enough about
    CLR)

    At the moment the whole:

    lock(anobject)
    {
    threadsafevar = new something(1,2,3 ,4,5); // is this needed for both value
    and ref types?
    }

    Is fine, but it would be really good be able to *require* that a particular
    variable was locked before access.

    Thanks,

    John


  • Thomas P. Skinner [MVP]

    #2
    Re: Threadsafe value types

    I am not sure I know what you mean by immutable in this context. Strings are
    immutable by virtue of the fact that if you try to assign to a string a new
    string is created. This means a new reference is generated. Value types like
    int etc. can be made readonly and can't be assigned to once initialized.

    As far as I know there is absolutely no way to force a programmer to use
    lock. You should also be aware that the volatile keyword should be used
    with fields used with multi-threaded applications to prevent compiler
    optimizations that cause caching and hence problems regardless of the use of
    the lock. If something is accessed in more than one thread it make no
    difference if it is a value or reference type.

    Thomas P. Skinner [MVP]

    "John" <jsparrowNOSPAM @ecclesdeleteth iscollege.ac.uk > wrote in message
    news:uEaUT%23Bx EHA.2676@TK2MSF TNGP12.phx.gbl. ..[color=blue]
    > If a value type is immutable, I guess it's threadsafe to read it? But not
    > threadsafe to assign a new value to it (can any value type be truely
    > immutable? Isn't assigning a totally new value to it, like doing an
    > modification, when no references are involved? I don't know enough about
    > CLR)
    >
    > At the moment the whole:
    >
    > lock(anobject)
    > {
    > threadsafevar = new something(1,2,3 ,4,5); // is this needed for both value
    > and ref types?
    > }
    >
    > Is fine, but it would be really good be able to *require* that a
    > particular variable was locked before access.
    >
    > Thanks,
    >
    > John
    >[/color]


    Comment

    • John

      #3
      Re: Threadsafe value types

      Hi Thomas,

      There seem to me many types I can't make volatile.. including any structs
      I've made, and DateTimes!

      I thought lock() removed the need for 'volatile'?

      By immutable value types I meant ones like DateTime, where you can't alter
      fields / properties, except by creating a new instance. This seems to be
      seen as 'a good thing' by the C# boffins at Microsoft. That whiteboard
      lecture on MSDN TV certainly indicated it was (I need to get out more).

      However, with my limited understanding of CLR, I would have thought that:

      DateTime a = new DateTime(1970,1 ,1);
      ....
      a = new DateTime(1971,1 ,1);

      is actually breaking the immutability of 'a'. It's a value type, so are we
      effectively changing it by doing something like 'year = 1971'? Or would the
      old 'a' still exist somewhere until it's GCed?


      "Thomas P. Skinner [MVP]" <tom@bu.edu> wrote in message
      news:u20fBoCxEH A.3808@TK2MSFTN GP15.phx.gbl...[color=blue]
      >I am not sure I know what you mean by immutable in this context. Strings
      >are immutable by virtue of the fact that if you try to assign to a string a
      >new string is created. This means a new reference is generated. Value types
      >like int etc. can be made readonly and can't be assigned to once
      >initialized.
      >
      > As far as I know there is absolutely no way to force a programmer to use
      > lock. You should also be aware that the volatile keyword should be used
      > with fields used with multi-threaded applications to prevent compiler
      > optimizations that cause caching and hence problems regardless of the use
      > of the lock. If something is accessed in more than one thread it make no
      > difference if it is a value or reference type.
      >
      > Thomas P. Skinner [MVP]
      >
      > "John" <jsparrowNOSPAM @ecclesdeleteth iscollege.ac.uk > wrote in message
      > news:uEaUT%23Bx EHA.2676@TK2MSF TNGP12.phx.gbl. ..[color=green]
      >> If a value type is immutable, I guess it's threadsafe to read it? But not
      >> threadsafe to assign a new value to it (can any value type be truely
      >> immutable? Isn't assigning a totally new value to it, like doing an
      >> modification, when no references are involved? I don't know enough about
      >> CLR)
      >>
      >> At the moment the whole:
      >>
      >> lock(anobject)
      >> {
      >> threadsafevar = new something(1,2,3 ,4,5); // is this needed for both
      >> value and ref types?
      >> }
      >>
      >> Is fine, but it would be really good be able to *require* that a
      >> particular variable was locked before access.
      >>
      >> Thanks,
      >>
      >> John
      >>[/color]
      >
      >[/color]


      Comment

      • Thomas P. Skinner [MVP]

        #4
        Re: Threadsafe value types

        You are correct. A struct can't be made volatile. Any reference type can as
        well as various ints, floats, char and enum. They must be fields however.

        As to your example, Just make it readonly. Consider this:

        int i=1;
        int i=2;

        i is not immutable, but the 1 and the 2 are. Same thing with DateTime.

        Thomas P. Skinner [MVP]

        "John" <jsparrowNOSPAM @ecclesdeleteth iscollege.ac.uk > wrote in message
        news:%23RznzeDx EHA.4004@tk2msf tngp13.phx.gbl. ..[color=blue]
        > Hi Thomas,
        >
        > There seem to me many types I can't make volatile.. including any structs
        > I've made, and DateTimes!
        >
        > I thought lock() removed the need for 'volatile'?
        >
        > By immutable value types I meant ones like DateTime, where you can't alter
        > fields / properties, except by creating a new instance. This seems to be
        > seen as 'a good thing' by the C# boffins at Microsoft. That whiteboard
        > lecture on MSDN TV certainly indicated it was (I need to get out more).
        >
        > However, with my limited understanding of CLR, I would have thought that:
        >
        > DateTime a = new DateTime(1970,1 ,1);
        > ...
        > a = new DateTime(1971,1 ,1);
        >
        > is actually breaking the immutability of 'a'. It's a value type, so are we
        > effectively changing it by doing something like 'year = 1971'? Or would
        > the old 'a' still exist somewhere until it's GCed?
        >
        >
        > "Thomas P. Skinner [MVP]" <tom@bu.edu> wrote in message
        > news:u20fBoCxEH A.3808@TK2MSFTN GP15.phx.gbl...[color=green]
        >>I am not sure I know what you mean by immutable in this context. Strings
        >>are immutable by virtue of the fact that if you try to assign to a string
        >>a new string is created. This means a new reference is generated. Value
        >>types like int etc. can be made readonly and can't be assigned to once
        >>initialized .
        >>
        >> As far as I know there is absolutely no way to force a programmer to use
        >> lock. You should also be aware that the volatile keyword should be used
        >> with fields used with multi-threaded applications to prevent compiler
        >> optimizations that cause caching and hence problems regardless of the use
        >> of the lock. If something is accessed in more than one thread it make no
        >> difference if it is a value or reference type.
        >>
        >> Thomas P. Skinner [MVP]
        >>
        >> "John" <jsparrowNOSPAM @ecclesdeleteth iscollege.ac.uk > wrote in message
        >> news:uEaUT%23Bx EHA.2676@TK2MSF TNGP12.phx.gbl. ..[color=darkred]
        >>> If a value type is immutable, I guess it's threadsafe to read it? But
        >>> not threadsafe to assign a new value to it (can any value type be truely
        >>> immutable? Isn't assigning a totally new value to it, like doing an
        >>> modification, when no references are involved? I don't know enough about
        >>> CLR)
        >>>
        >>> At the moment the whole:
        >>>
        >>> lock(anobject)
        >>> {
        >>> threadsafevar = new something(1,2,3 ,4,5); // is this needed for both
        >>> value and ref types?
        >>> }
        >>>
        >>> Is fine, but it would be really good be able to *require* that a
        >>> particular variable was locked before access.
        >>>
        >>> Thanks,
        >>>
        >>> John
        >>>[/color]
        >>
        >>[/color]
        >
        >[/color]


        Comment

        • Jeff Louie

          #5
          Re: Threadsafe value types

          John... As Thomas suggested if you declare the variable readonly the
          compiler appears to block setters in the structure.

          Regards,
          Jeff[color=blue]
          >If a value type is immutable, I guess it's threadsafe to read it? But[/color]
          not threadsafe to assign a new value to it(can any value type be truely
          immutable?<

          ====== code =============

          using System;

          namespace TestStruct
          {
          public struct MutableS
          {
          private int i;
          public int I
          {
          get {return i;}
          set {this.i= value;}
          }
          public MutableS(int i)
          {
          this.i=i;
          }
          }

          /// <summary>
          /// Summary description for Class1.
          /// </summary>
          class Class1
          {
          static readonly MutableS ro_sm= new MutableS(1);
          static MutableS sm= new MutableS(2);
          /// <summary>
          /// The main entry point for the application.
          /// </summary>
          [STAThread]
          static void Main(string[] args)
          {
          //
          // TODO: Add code to start application here
          //
          //Class1.ro_sm.I= 3; // will not compile!
          Class1.sm.I= 4;
          }
          }
          }



          *** Sent via Developersdex http://www.developersdex.com ***
          Don't just participate in USENET...get rewarded for it!

          Comment

          • John

            #6
            Re: Modifying value types

            Thanks for the help guys.

            So is there no added value in having a create-only value type like DateTime,
            that doesn't give write access to it's fields / properties?

            MSDN gives the impression struct's that allow field modification are bad -
            but I can't see why if these two are equivelent:

            // editable struct instance
            DateTime a = new DateTime(1970,1 ,1);
            a.ChangeDay(2); // a fictional method I made up to alter the
            DateTime struct!

            ....and...

            // new struct instance
            DateTime a = new DateTime(1970,1 ,1);
            a = new DateTime(1970,1 ,2);

            Would these be functional equivelent?

            John

            "Jeff Louie" <jeff_louie@yah oo.com> wrote in message
            news:O3cj6nFxEH A.3024@TK2MSFTN GP14.phx.gbl...[color=blue]
            > John... As Thomas suggested if you declare the variable readonly the
            > compiler appears to block setters in the structure.
            >
            > Regards,
            > Jeff[color=green]
            >>If a value type is immutable, I guess it's threadsafe to read it? But[/color]
            > not threadsafe to assign a new value to it(can any value type be truely
            > immutable?<
            >
            > ====== code =============
            >
            > using System;
            >
            > namespace TestStruct
            > {
            > public struct MutableS
            > {
            > private int i;
            > public int I
            > {
            > get {return i;}
            > set {this.i= value;}
            > }
            > public MutableS(int i)
            > {
            > this.i=i;
            > }
            > }
            >
            > /// <summary>
            > /// Summary description for Class1.
            > /// </summary>
            > class Class1
            > {
            > static readonly MutableS ro_sm= new MutableS(1);
            > static MutableS sm= new MutableS(2);
            > /// <summary>
            > /// The main entry point for the application.
            > /// </summary>
            > [STAThread]
            > static void Main(string[] args)
            > {
            > //
            > // TODO: Add code to start application here
            > //
            > //Class1.ro_sm.I= 3; // will not compile!
            > Class1.sm.I= 4;
            > }
            > }
            > }
            >
            >
            >
            > *** Sent via Developersdex http://www.developersdex.com ***
            > Don't just participate in USENET...get rewarded for it![/color]


            Comment

            • Jon Skeet [C# MVP]

              #7
              Re: Threadsafe value types

              Thomas P. Skinner [MVP] <tom@bu.edu> wrote:

              <snip>
              [color=blue]
              > You should also be aware that the volatile keyword should be used
              > with fields used with multi-threaded applications to prevent compiler
              > optimizations that cause caching and hence problems regardless of the use of
              > the lock.[/color]

              That's not true. Acquiring a lock involves a volatile read, and
              releasing it involves a volatile write, so volatility isn't required if
              you're using locks appropriately.

              See http://www.pobox.com/~skeet/csharp/t...latility.shtml

              --
              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

              • Thomas P. Skinner [MVP]

                #8
                Re: Threadsafe value types

                This is a good point but the use of a lock does not actually eliminate the
                compiler or runtime from optimizations on fields not marked as volatile.
                Sure, if all accesses are inside the locked block then there would be no
                problems in practice. But having knowledge of the existence of the volatile
                modifier is certainly worthwhile.

                Thomas P. Skinner [MVP]


                "Jon Skeet [C# MVP]" <skeet@pobox.co m> wrote in message
                news:MPG.1bf877 1dd935c3cc98b89 0@msnews.micros oft.com...[color=blue]
                > Thomas P. Skinner [MVP] <tom@bu.edu> wrote:
                >
                > <snip>
                >[color=green]
                >> You should also be aware that the volatile keyword should be used
                >> with fields used with multi-threaded applications to prevent compiler
                >> optimizations that cause caching and hence problems regardless of the use
                >> of
                >> the lock.[/color]
                >
                > That's not true. Acquiring a lock involves a volatile read, and
                > releasing it involves a volatile write, so volatility isn't required if
                > you're using locks appropriately.
                >
                > See http://www.pobox.com/~skeet/csharp/t...latility.shtml
                >
                > --
                > Jon Skeet - <skeet@pobox.co m>
                > http://www.pobox.com/~skeet
                > If replying to the group, please do not mail me too[/color]


                Comment

                • Jeff Louie

                  #9
                  Re: Modifying value types

                  John....>So is there no added value in having a create-only value type
                  like
                  DateTime, that doesn't give write access to it's fields / properties?<

                  A very good question. Most would not argue about the advantages of using
                  immutable classes. The advantages for immutable structures are less
                  obvious
                  since they use value semantics and provide automatic "defensive copies."
                  Still
                  immutable structures are going to be simple, reliable and useful for
                  building
                  complex objects.

                  Let me turn the question around. Since most structures are simple small
                  constructs that are easily passed and copied using value semantics, why
                  not
                  simplify your life/code and write only immutable structures? A typical
                  method
                  might take an "instance" of a value type and return a different
                  "instance" of
                  the same value type or just it may just read the value. So a typical
                  method
                  would not need access to any setters outside of initialization which can
                  be
                  done in the constructor.

                  So immutable structures are simpler and more reliable than mutable
                  structures, but may be harder to initialize since you must know the
                  proper
                  order to pass the arguments to the constructor as opposed to using named
                  setters.
                  [color=blue]
                  >// editable struct instance[/color]
                  DateTime a = new DateTime(1970,1 ,1);
                  a.ChangeDay(2); // a fictional method I made up to alter the
                  DateTime struct!

                  ....and...

                  // new struct instance
                  DateTime a = new DateTime(1970,1 ,1);
                  a = new DateTime(1970,1 ,2);

                  Would these be functional equivelent?<

                  In the sense that the containing object's state is mutated either way,
                  yes. So
                  to _build_ a immutable class (as opposed to using a immutable class) "a"
                  should be private. You can do anything you want within the class as long
                  as
                  no method makes an externally visible change in the objects state and
                  the
                  object does not violate an invariant for which it is responsible.

                  Regards,
                  Jeff



                  *** Sent via Developersdex http://www.developersdex.com ***
                  Don't just participate in USENET...get rewarded for it!

                  Comment

                  • Jon Skeet [C# MVP]

                    #10
                    Re: Threadsafe value types

                    Thomas P. Skinner [MVP] <tom@bu.edu> wrote:[color=blue]
                    > This is a good point but the use of a lock does not actually eliminate the
                    > compiler or runtime from optimizations on fields not marked as volatile.[/color]

                    Not outside the lock, no. But then if you're using locks in some
                    places, you almost certainly shouldn't be accessing the variables
                    without acquiring a lock in *all* places anyway. There's no need to use
                    the volatile modifier to achieve thread safety, contrary to the
                    statement in your earlier post.
                    [color=blue]
                    > Sure, if all accesses are inside the locked block then there would be no
                    > problems in practice.[/color]

                    And none in theory either. If we were only talking about "in practice"
                    scenarios, there's an awful lot you can get away with which I wouldn't
                    recommend.
                    [color=blue]
                    > But having knowledge of the existence of the volatile
                    > modifier is certainly worthwhile.[/color]

                    Undoubtedly, although I prefer not to use volatile fields myself, using
                    locks instead.

                    --
                    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...