Refcountedthreadsafe's reference count is atomic, so the online search for unified parlance thread safety, Refcountedthreadsafe also has a lot of non-atomic operations, what does it mean by thread safety?
For example, is it thread safe to refcountedthreadsafe across threads with scoped_refptr operations?
Write a simple sample test:
Class Test:public base::refcountedthreadsafe<test>
{public
:
Test () {}
private:
friend Class base::refcountedthreadsafe<test>;
~test ()
{
int i = 0;
}
};
Scoped_refptr<test> g_ptest;
DWORD WINAPI ThreadProc1 (lpvoid lpparameter)
{
g_ptest = NULL;
return 0;
}
DWORD WINAPI ThreadProc2 (lpvoid lpparameter)
{
scoped_refptr<test> pother;
if (g_ptest)
{
pother = g_ptest;
}
return 0;
}
void Fun ()
{
g_ptest = new Test;
DWORD dwThreadId1 = 0;
:: CreateThread (NULL,0,THREADPROC1,NULL,0,&DWTHREADID1);
DWORD dwThreadId2 = 0;
:: CreateThread (NULL,0,THREADPROC2,NULL,0,&DWTHREADID2);
}
The above is two threads, a test function, first set breakpoints in ThreadProc1 and THREADPROC2, the general will first break in ThreadProc1, the initial g_ptest reference count is 1, see the following figure:
Single-Step test jump in, scoped_refptr<t>& operator= (t* p)
Set a breakpoint, as shown below:
at this point, switch to the THREADPROC2 thread:
Because G_ptest has not yet performed the Ptr_ assignment, Ptr_ is a value, that is, if (g_ptest) is OK, because Pother = G_ptest;,scoped_refptr also goes to the assignment operation Scoped_refptr<t >& operator= (t* p), note that this is in the THREADPROC2 thread, and we break it before it executes the AddRef (that is, the reference count has not yet + 1):
at this point, switch back to the THREADPROC1 thread:
Let ThreadProc1 execute its assignment and delete operation, and finally go to test's destructor, that is, 0x01c85588 this address is released
at this point, switch to the THREADPROC2 thread:
It is going to execute p->addref, because P (0x01c85588), this address has been released, then this ptr_-> what kind of error will appear, it is unclear,
Finally, when Pother is released, the following box pops up:
So scoped_refptr using refcountedthreadsafe should not be thread-safe, the same test weakptr, before is_valid_ = False, let the weakptr get first, is valid, but the actual object has been destructor, will also over,
But if we are in the call line enters upgradeable AddRef, on other threads to release, it feels like thread-safe, like a typical task
Why should I avoid reference counting?
Explanation in the Chromium smart pointer Guide:
reference-counted objects make it difficult to understand ownership and destruction order, especially when multiple thread S is involved. There is almost always another-to design your object hierarchy to avoid refcounting. Avoiding refcounting in multithreaded situations are usually easier if you restrict each class to operating on just one THR EAD, and use Posttask () and the As to proxy calls to the correct thread. Base::bind (), Weakptr, and other tools make it possible to automatically cancel calls to such a object when it dies. Note that too much of We existing code uses refcounting, so just because do see existing code doing it does not mean it ' s the right solution. (Bonus points if you ' re able to clean up such cases.)