{"id":3013,"date":"2011-05-26T17:50:51","date_gmt":"2011-05-26T17:50:51","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vcblog\/2011\/05\/26\/enforcing-correct-concurrent-access-of-class-data\/"},"modified":"2021-10-04T17:56:36","modified_gmt":"2021-10-04T17:56:36","slug":"enforcing-correct-concurrent-access-of-class-data","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/enforcing-correct-concurrent-access-of-class-data\/","title":{"rendered":"Enforcing Correct Concurrent Access of Class Data"},"content":{"rendered":"<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2011\/05\/7183.image_0C7B3B88.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2011\/05\/7183.image_0C7B3B88.png\" alt=\"Jim Springfield\" width=\"73\" height=\"96\" class=\"alignleft size-full wp-image-29157\" \/><\/a><\/p>\n<p>Hi, this is <strong>Jim Springfield<\/strong>. I&rsquo;m an architect on the Visual C++ team.<\/p>\n<p>In any concurrent application, protecting data from concurrent access is extremely important. There are many primitives that can be used for this, such as critical sections, mutexes, reader-writer locks, etc. There are also some newer high-level approaches to concurrency such as those provided by the <a target=\"_blank\" href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/dd504870.aspx\" rel=\"noopener\">Concurrency Runtime<\/a>, although this isn&rsquo;t the focus of what I&rsquo;m showing here. However, there isn&rsquo;t a good way in C++ to make sure that you are really protecting data correctly when accessing it from multiple threads. You will often see a comment (likely made by the original author) next to a member that reminds you to take some lock when accessing the data. There may be many data items all using the same lock and there may be more than one lock, with some data protected by one lock and some by another.<\/p>\n<p>When it comes time to access some data from a member function, you have to start asking some questions. Who is going to call this member? What locks will already be held? Could I deadlock here? While I don&rsquo;t have a solution to all of these, I do have a technique that allows you to be more aggressive with trying things and more comfortable with making changes to existing code, while guaranteeing that you don&rsquo;t violate the requirement that a particular lock is held.<\/p>\n<p>What I&rsquo;m going to show is a way to associate a lock with a data member such that whenever that data member is accessed, a check is made that the proper lock is held by the thread. The basis for the technique uses <a target=\"_blank\" href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/yhfk0thd.aspx\" rel=\"noopener\">native properties<\/a> to provide access to data members. With a small set of macros, you can easily retrofit existing code to provide this benefit. I developed this technique years ago and I have used it in several code bases to catch problems with concurrent access.<\/p>\n<p>Here is an example of something you will typically see in code. The developer has written that a critical section should be held when accessing <span style=\"font-family: Courier New\">m_rgContextsCache<\/span>.<\/p>\n<div class=\"wlWriterEditableSmartContent\" style=\"margin: 0px;float: none;padding: 0px\">\n<div style=\"border: #000080 1px solid;color: #000;font-family: 'Courier New', Courier, Monospace;font-size: 10pt\">\n<div style=\"background: #fff;overflow: auto\">\n<ol style=\"background: #ffffff;margin: 0;padding: 0 0 0 5px\">\n<li><span style=\"color: #008000\">\/\/ Make sure m_cs is held when accessing m_rgContextsCache<\/span><\/li>\n<li style=\"background: #f3f3f3\">vector&lt;FileConfig&gt; m_rgContextsCache;<\/li>\n<\/ol>\n<\/div>\n<\/div>\n<\/div>\n<p>Wouldn&rsquo;t it be great if this information could be specified in code AND enforced? The code below shows how to transform this into just that.<\/p>\n<div class=\"wlWriterEditableSmartContent\" style=\"margin: 0px;float: none;padding: 0px\">\n<div style=\"border: #000080 1px solid;color: #000;font-family: 'Courier New', Courier, Monospace;font-size: 10pt\">\n<div style=\"background: #fff;overflow: auto\">\n<ol style=\"background: #ffffff;margin: 0;padding: 0 0 0 5px\">\n<li>PROTECTED_MEMBER(m_cs, vector&lt;FileConfig&gt;, m_rgContextsCache);<\/li>\n<\/ol>\n<\/div>\n<\/div>\n<\/div>\n<p>Now, whenever <span style=\"font-family: Courier New\">m_rgContextsCache<\/span> is accessed, a user-defined function will be called if the proper lock is not held. What the macro does is to create the actual data member with a slightly modified name and a property with the name specified. Now, all you have to do is run your code and see if any errors occur. There is one &ldquo;<em>gotcha<\/em>&rdquo;. When members are initialized in the constructor or referenced in a destructor, the lock isn&rsquo;t going to be held. For those cases, you need to directly access the member. A macro that translates a name into the modified &ldquo;real&rdquo; name can be used. It can also be used anywhere that it is specifically safe to access the member outside of the lock. The nice thing is that it is now very clear when you are doing this. Here is the code for this.<\/p>\n<div class=\"wlWriterEditableSmartContent\" style=\"margin: 0px;float: none;padding: 0px\">\n<div style=\"border: #000080 1px solid;color: #000;font-family: 'Courier New', Courier, Monospace;font-size: 10pt\">\n<div style=\"background: #fff;overflow: auto\">\n<ol style=\"background: #ffffff;margin: 0;padding: 0 0 0 5px\">\n<li><span style=\"color: #008000\">\/\/ The USN macro is used when you need to access a data member in an &#8220;unsafe&#8221; way.<\/span><\/li>\n<li style=\"background: #f3f3f3\"><span style=\"color: #008000\">\/\/ This makes sense when you know no other thread is accessing it, such as in a constructor.<\/span><\/li>\n<li><span style=\"color: #0000ff\">#define<\/span> USN(name) name##_usn_<\/li>\n<\/ol>\n<\/div>\n<\/div>\n<\/div>\n<p>The <span style=\"font-family: Courier New\">PROTECTED_MEMBER<\/span> macro is defined below. The first line creates the actual member. The second line creates the property and the remaining lines implement the get and put.<\/p>\n<div class=\"wlWriterEditableSmartContent\" style=\"margin: 0px;float: none;padding: 0px\">\n<div style=\"border: #000080 1px solid;color: #000;font-family: 'Courier New', Courier, Monospace;font-size: 10pt\">\n<div style=\"background: #fff;overflow: auto\">\n<ol style=\"background: #ffffff;margin: 0;padding: 0 0 0 5px\">\n<li><span style=\"color: #0000ff\">#define<\/span> PROTECTED_MEMBER(cs, type, name) \\<\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;type USN(name);\\<\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color: #0000ff\">__declspec<\/span>(<span style=\"color: #0000ff\">property<\/span>(get=Get_<span style=\"color: #0000ff\">#<\/span>#name, put=Put_##name)) type name;\\<\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;type &amp; Get_<span style=\"color: #0000ff\">#<\/span>#name()\\<\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;{_PROTECT(verify_lock(cs));<span style=\"color: #0000ff\">return<\/span> USN(name);}\\<\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;type <span style=\"color: #0000ff\">const<\/span> &amp; Get_<span style=\"color: #0000ff\">#<\/span>#name() <span style=\"color: #0000ff\">const\\<\/span><\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;{_PROTECT(verify_lock(cs));<span style=\"color: #0000ff\">return<\/span> USN(name);}\\<\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;type &amp; Put_<span style=\"color: #0000ff\">#<\/span>#name(type <span style=\"color: #0000ff\">const<\/span> &amp; x)\\<\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;{_PROTECT(verify_lock(cs));USN(name) = x;<span style=\"color: #0000ff\">return<\/span> USN(name);}<\/li>\n<\/ol>\n<\/div>\n<\/div>\n<\/div>\n<p>There are a couple of things that aren&rsquo;t defined yet. The <span style=\"font-family: Courier New\">verify_lock<\/span> function will return a boolean indicating whether the lock is held or not. These can be defined for any type of lock you use. There is also the <span style=\"font-family: Courier New\">_PROTECT<\/span> macro. This should be defined to do whatever you want in the case of a failure. This could log, assert, crash, etc.<\/p>\n<p>There are some other variations of the macro to handle some additional cases. One is to handle arrays. It provides a parameterized property which handles the index.<\/p>\n<div class=\"wlWriterEditableSmartContent\" style=\"margin: 0px;float: none;padding: 0px\">\n<div style=\"border: #000080 1px solid;color: #000;font-family: 'Courier New', Courier, Monospace;font-size: 10pt\">\n<div style=\"background: #fff;overflow: auto\">\n<ol style=\"background: #ffffff;margin: 0;padding: 0 0 0 5px\">\n<li><span style=\"color: #0000ff\">#define<\/span> PROTECTED_MEMBER_ARRAY(cs, elemtype, name, length) \\<\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color: #0000ff\">typedef<\/span> elemtype type_<span style=\"color: #0000ff\">#<\/span>#name[length];\\<\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;elemtype USN(name)[length];\\<\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color: #0000ff\">__declspec<\/span>(<span style=\"color: #0000ff\">property<\/span>(get=Get_<span style=\"color: #0000ff\">#<\/span>#name, put=Put_##name)) elemtype name[length];\\<\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;elemtype&amp; Get_<span style=\"color: #0000ff\">#<\/span>#name(size_t i)\\<\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;{_PROTECT(verify_lock(cs));<span style=\"color: #0000ff\">return<\/span> USN(name)[i];}\\<\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;type_<span style=\"color: #0000ff\">#<\/span>#name&amp; Get_##name()\\<\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;{_PROTECT(verify_lock(cs));<span style=\"color: #0000ff\">return<\/span> USN(name);}\\<\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color: #0000ff\">const<\/span> elemtype&amp; Put_<span style=\"color: #0000ff\">#<\/span>#name(size_t i, elemtype <span style=\"color: #0000ff\">const<\/span>&amp; x)\\<\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;{_PROTECT(verify_lock(cs));USN(name)[i] = x;<span style=\"color: #0000ff\">return<\/span> USN(name)[i];}<\/li>\n<\/ol>\n<\/div>\n<\/div>\n<\/div>\n<p>To handle a reader-writer lock, a slightly different macro is used. Instead of &ldquo;<span style=\"font-family: Courier New\">verify_lock<\/span>&rdquo;, two other functions are used: <span style=\"font-family: Courier New\">verify_readlock<\/span> and <span style=\"font-family: Courier New\">verify_writelock<\/span>. Again, these can be user-defined to handle any type of reader-writer lock. There is one additional wrinkle here, however. There is a function defined called &ldquo;<span style=\"font-family: Courier New\">GetWritable_##name<\/span>&rdquo;. The getter returns a <span style=\"font-family: Courier New\">const&amp;<\/span> to the underlying member and verifies that a read lock is held, but this won&rsquo;t allow you to call methods on it that modify it. To do that, you have to explicitly call <span style=\"font-family: Courier New\">GetWritable_##name<\/span>. This will return a non-const reference and verify the write lock is held.<\/p>\n<div class=\"wlWriterEditableSmartContent\" style=\"margin: 0px;float: none;padding: 0px\">\n<div style=\"border: #000080 1px solid;color: #000;font-family: 'Courier New', Courier, Monospace;font-size: 10pt\">\n<div style=\"background: #fff;overflow: auto\">\n<ol style=\"background: #ffffff;margin: 0;padding: 0 0 0 5px\">\n<li><span style=\"color: #0000ff\">#define<\/span> PROTECTED_MEMBER_RW(lock, type, name) \\<\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;type USN(name);\\<\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color: #0000ff\">__declspec<\/span>(<span style=\"color: #0000ff\">property<\/span>(get=Get_<span style=\"color: #0000ff\">#<\/span>#name, put=Put_##name)) type name;\\<\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color: #0000ff\">const<\/span> type &amp; Get_<span style=\"color: #0000ff\">#<\/span>#name()\\<\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;{_PROTECT(verify_readlock(lock));<span style=\"color: #0000ff\">return<\/span> USN(name);}\\<\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;type &amp; Put_<span style=\"color: #0000ff\">#<\/span>#name(type <span style=\"color: #0000ff\">const<\/span>&amp; x)\\<\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;{_PROTECT(verify_writelock(lock));USN(name) = x;<span style=\"color: #0000ff\">return<\/span> USN(name);}\\<\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color: #0000ff\">__declspec<\/span>(<span style=\"color: #0000ff\">property<\/span>(get=GetWritable_<span style=\"color: #0000ff\">#<\/span>#name)) type Writable_##name;\\<\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;type &amp; GetWritable_<span style=\"color: #0000ff\">#<\/span>#name()\\<\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;{_PROTECT(verify_writelock(lock));<span style=\"color: #0000ff\">return<\/span> USN(name);}<\/li>\n<\/ol>\n<\/div>\n<\/div>\n<\/div>\n<p>There are a couple of other variations to the <span style=\"font-family: Courier New\">PROTECTED_MEMBER<\/span> macro to handle some cases that can occur. If the data member can&rsquo;t be assigned to (i.e. it is a type without assignment), we need to not provide a &ldquo;Put&rdquo; or we will get a compile error. Similarly, we may have a type that can&rsquo;t be assigned from <span style=\"font-family: Courier New\">const<\/span> data. These cases occur rarely in practice, but they do occur.<\/p>\n<div class=\"wlWriterEditableSmartContent\" style=\"margin: 0px;float: none;padding: 0px\">\n<div style=\"border: #000080 1px solid;color: #000;font-family: 'Courier New', Courier, Monospace;font-size: 10pt\">\n<div style=\"background: #fff;overflow: auto\">\n<ol style=\"background: #ffffff;margin: 0;padding: 0 0 0 5px\">\n<li><span style=\"color: #0000ff\">#define<\/span> PROTECTED_MEMBER_NC(cs, type, name) \\<\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;type USN(name);\\<\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color: #0000ff\">__declspec<\/span>(<span style=\"color: #0000ff\">property<\/span>(get=Get_<span style=\"color: #0000ff\">#<\/span>#name, put=Put_##name)) type name;\\<\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;type &amp; Get_<span style=\"color: #0000ff\">#<\/span>#name()\\<\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;{_PROTECT(verify_lock(cs));<span style=\"color: #0000ff\">return<\/span> USN(name);}\\<\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;type <span style=\"color: #0000ff\">const<\/span> &amp; Get_<span style=\"color: #0000ff\">#<\/span>#name() <span style=\"color: #0000ff\">const\\<\/span><\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;{_PROTECT(verify_lock(cs));<span style=\"color: #0000ff\">return<\/span> USN(name);}\\<\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color: #0000ff\">template<\/span> &lt;<span style=\"color: #0000ff\">typename<\/span> T&gt;\\<\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;type &amp; Put_<span style=\"color: #0000ff\">#<\/span>#name(T x)\\<\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;{_PROTECT(verify_lock(cs));USN(name) = x;<span style=\"color: #0000ff\">return<\/span> USN(name);}\\<\/li>\n<li>&nbsp;<\/li>\n<li style=\"background: #f3f3f3\"><span style=\"color: #0000ff\">#define<\/span> PROTECTED_MEMBER_GET(cs, type, name) \\<\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;type USN(name);\\<\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color: #0000ff\">__declspec<\/span>(<span style=\"color: #0000ff\">property<\/span>(get=Get_<span style=\"color: #0000ff\">#<\/span>#name, put=Put_##name)) type name;\\<\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;type &amp; Get_<span style=\"color: #0000ff\">#<\/span>#name()\\<\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;{_PROTECT(verify_lock(cs));<span style=\"color: #0000ff\">return<\/span> USN(name);}\\<\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;type <span style=\"color: #0000ff\">const<\/span> &amp; Get_<span style=\"color: #0000ff\">#<\/span>#name() <span style=\"color: #0000ff\">const\\<\/span><\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;{_PROTECT(verify_lock(cs));<span style=\"color: #0000ff\">return<\/span> USN(name);}<\/li>\n<\/ol>\n<\/div>\n<\/div>\n<\/div>\n<p>Finally, here are some examples of <span style=\"font-family: Courier New\">verify_lock<\/span> and <span style=\"font-family: Courier New\">verify_unlock<\/span> that can handle critical sections by pointer or by reference.<\/p>\n<div class=\"wlWriterEditableSmartContent\" style=\"margin: 0px;float: none;padding: 0px\">\n<div style=\"border: #000080 1px solid;color: #000;font-family: 'Courier New', Courier, Monospace;font-size: 10pt\">\n<div style=\"background: #fff;overflow: auto\">\n<ol style=\"background: #ffffff;margin: 0;padding: 0 0 0 5px\">\n<li><span style=\"color: #0000ff\">inline<\/span> <span style=\"color: #0000ff\">bool<\/span> verify_lock(<span style=\"color: #0000ff\">const<\/span> CRITICAL_SECTION&amp; cs)<\/li>\n<li style=\"background: #f3f3f3\">{<\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color: #0000ff\">return<\/span> (cs.OwningThread == (HANDLE)(UINT_PTR)GetCurrentThreadId());<\/li>\n<li style=\"background: #f3f3f3\">}<\/li>\n<li><span style=\"color: #0000ff\">inline<\/span> <span style=\"color: #0000ff\">bool<\/span> verify_unlock(<span style=\"color: #0000ff\">const<\/span> CRITICAL_SECTION&amp; cs)<\/li>\n<li style=\"background: #f3f3f3\">{<\/li>\n<li>&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color: #0000ff\">return<\/span> (cs.OwningThread == (HANDLE)(UINT_PTR)0);<\/li>\n<li style=\"background: #f3f3f3\">}<\/li>\n<li>&nbsp;<\/li>\n<li style=\"background: #f3f3f3\"><span style=\"color: #0000ff\">inline<\/span> <span style=\"color: #0000ff\">bool<\/span> verify_lock(<span style=\"color: #0000ff\">const<\/span> CRITICAL_SECTION* cs)<\/li>\n<li>{<\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color: #0000ff\">return<\/span> (cs-&gt;OwningThread == (HANDLE)(UINT_PTR)GetCurrentThreadId());<\/li>\n<li>}<\/li>\n<li style=\"background: #f3f3f3\"><span style=\"color: #0000ff\">inline<\/span> <span style=\"color: #0000ff\">bool<\/span> verify_unlock(<span style=\"color: #0000ff\">const<\/span> CRITICAL_SECTION* cs)<\/li>\n<li>{<\/li>\n<li style=\"background: #f3f3f3\">&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color: #0000ff\">return<\/span> (cs-&gt;OwningThread == (HANDLE)(UINT_PTR)0);<\/li>\n<li>}<\/li>\n<\/ol>\n<\/div>\n<\/div>\n<\/div>\n<p>What I typically do is put all of these macros in a header file under an <span style=\"font-family: Courier New\">#ifdef _PROTECT<\/span> guard. If <span style=\"font-family: Courier New\">_PROTECT<\/span> is not defined, then I simply let everything collapse to simple data members. For release builds, the code is just as fast as before.<\/p>\n<div class=\"wlWriterEditableSmartContent\" style=\"margin: 0px;float: none;padding: 0px\">\n<div style=\"border: #000080 1px solid;color: #000;font-family: 'Courier New', Courier, Monospace;font-size: 10pt\">\n<div style=\"background: #fff;overflow: auto\">\n<ol style=\"background: #ffffff;margin: 0;padding: 0 0 0 5px\">\n<li><span style=\"color: #0000ff\">#ifdef<\/span> _PROTECT<\/li>\n<li style=\"background: #f3f3f3\"><span style=\"color: #008000\">\/\/ All of the code from above<\/span><\/li>\n<li><span style=\"color: #0000ff\">#else<\/span><\/li>\n<li style=\"background: #f3f3f3\"><span style=\"color: #0000ff\">#define<\/span> USN(name) name<\/li>\n<li><span style=\"color: #0000ff\">#define<\/span> PROTECTED_MEMBER(cs, type, name) type name;<\/li>\n<li style=\"background: #f3f3f3\"><span style=\"color: #0000ff\">#define<\/span> PROTECTED_MEMBER_NC(cs, type, name) type name;<\/li>\n<li><span style=\"color: #0000ff\">#define<\/span> PROTECTED_MEMBER_GET(cs, type, name) type name;<\/li>\n<li style=\"background: #f3f3f3\"><span style=\"color: #0000ff\">#define<\/span> PROTECTED_MEMBER_RW(cs, type, name) type name;<\/li>\n<li><span style=\"color: #0000ff\">#define<\/span> PROTECTED_MEMBER_ARRAY(cs, elemtype, name, length) elemtype name[length];<\/li>\n<li style=\"background: #f3f3f3\"><span style=\"color: #0000ff\">#endif<\/span><\/li>\n<\/ol>\n<\/div>\n<\/div>\n<\/div>\n<p>Finally, there is no good way that I&rsquo;ve found to do this for global or static member data. Usually, it isn&rsquo;t too much work to wrap global or static data into a class (along with the appropriate lock), which is what I&rsquo;ve done when I need to.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hi, this is Jim Springfield. I&rsquo;m an architect on the Visual C++ team. In any concurrent application, protecting data from concurrent access is extremely important. There are many primitives that can be used for this, such as critical sections, mutexes, reader-writer locks, etc. There are also some newer high-level approaches to concurrency such as those [&hellip;]<\/p>\n","protected":false},"author":289,"featured_media":35994,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[80],"class_list":["post-3013","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cplusplus","tag-parallelism"],"acf":[],"blog_post_summary":"<p>Hi, this is Jim Springfield. I&rsquo;m an architect on the Visual C++ team. In any concurrent application, protecting data from concurrent access is extremely important. There are many primitives that can be used for this, such as critical sections, mutexes, reader-writer locks, etc. There are also some newer high-level approaches to concurrency such as those [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/3013","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/users\/289"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/comments?post=3013"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/3013\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media\/35994"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media?parent=3013"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=3013"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=3013"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}