c++ - multithread race condition with use-counted shared pointer -


I have an old C ++ 98 code base that is in combination with use-count and pimpl design that can be up to 4 years Works fine - they are 8-way processors have become common and you see this in the Pimple code (this is actually a template in the original code):

  square fu {FooImpl * impl ; Public: Fu (): Implications (0) {} Foo & amp; Operator = (Const Foo & amp; Foo) {if (foo.impl) foo.impl- & gt; Adf (); If (impl & amp; amp; ;; removeRef ()); Impl = foo.impl; Return * This; } // etc}  

The problem is in a multiprocessor environment, function switching can occur between if (foo.impl) and foo.impl - & gt; AddRef () . The first idea to fix this can be:

  Foo & amp; Operator = (Const Foo & amp; Foo) {FooImpl * fooimpl = foo.impl; If (fooimpl) fooimpl- & gt; AddRef (); If (impl & amp; amp; ;; removeRef ()); Impl = fooimpl; Return * This; }  

but this problem does not resolve foo.impl still can be invalid when you call addRef () There is no way around this problem in which no semaphore is involved? If every assignment operator on the object is wrapped in a sequential display, then it will be negatively affected.

  Foo & amp; Operator = (constant foo and eff) {global_lock.acquire (); If (foo.impl) foo.impl- & gt; AddRef (); If (impl & amp; amp; ;; removeRef ()); Impl = foo.impl; Global_lock.release (); Return * This; }  

I suspect that the answer is "no".

For a reference calculation plan, objects need to be designed and used in such a way that you It can guarantee that Reference is always safe to add context as a thought experiment, why it works, consider two threads with reference to that same object. In such a scenario, there should never be any such case, where a thread perceives the reference number of 0, for the object transition, because its own context should be prevented from happening.

The problem you are describing should be the solution that the task that is crossing the context of any other work can move forward and easily add the context in advance. Below is a plan that shows:

  class FooImpl {friend class fu; Unsigned count; FooImpl (): Counting (1) {} Zero addRef () {++ count; } Bool removalRef () {Return! - Calculation; }}; Class Foo {FooImpl * impl; Zero addRef () {if (impl) impl- & gt; AddRef (); } Deletion (Reef) (If (Emporize & amp; & gt; Delete delete); Entrance;} zero swap (Foo & Foo) {FooImpl * tmp = impl; Impl = foo.impl; Foo.impl = Tmp;} Public: ~ Foo () {removeRef ();} Fu (): Implication (0) {} Fu (Const Foo and Foo): Impla (foo.impl) {addRef ();} Foo & amp; Operator = (Fu Fu) {Swap (Foo); Return * This;} // etc};  

Note, while the same FooImpl example Can be referenced by multiple threads, each thread has its own for the scheme Foo .


Comments

Popular posts from this blog

sqlite3 - UPDATE a table from the SELECT of another one -

c# - Showing a SelectedItem's Property -

javascript - Render HTML after each iteration in loop -