引用計數自動管理對象的生存周期

來源:互聯網
上載者:User

//
// 引用計數在長時間軸程過程中的使用
// cheungmine
//
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <process.h>

// It should be used if the worker class will use CRT functions
static HANDLE CrtCreateThread(LPSECURITY_ATTRIBUTES    lpsa,
                              DWORD                    dwStackSize,
                              LPTHREAD_START_ROUTINE   pfnThreadProc,
                              LPVOID                   pvParam,
                              DWORD                    dwCreationFlags,
                              LPDWORD                  pdwThreadId)
{
    // _beginthreadex calls CreateThread which will set the last error value before it returns
    return (HANDLE) _beginthreadex(lpsa,
                           dwStackSize,
                           (unsigned int (__stdcall *)(void *)) pfnThreadProc,
                           pvParam,
                           dwCreationFlags,
                           (unsigned int *) pdwThreadId);
}

class CUserdata
{
public:
    CUserdata():m_data(100)
    {
        printf("CUserdata()/n");

    }

    ~CUserdata()
    {
        printf("~CUserdata()/n");
    }

    int  m_data;

};

template< typename _Type > class ThreadParamT
{
    volatile  ULONG   m_cRef;

    // 私人的析構方法保證由引用計數自動管理對象的生存期
    ~ThreadParamT()
    {
        printf("~ThreadParamT()::m_cRef=%d/n", m_cRef);
    }
public:
    ULONG AddRef()
    {
        return (ULONG) InterlockedIncrement((volatile LONG*)&m_cRef);
    }
   
    ULONG Release()
    {
        if (InterlockedDecrement((volatile LONG*)&m_cRef)==0)
        {
            delete this;
            return 0;
        }
        return m_cRef;
    }

    ThreadParamT():
        m_cRef(1)
    {
        printf("ThreadParamT()::m_cRef=%d/n", m_cRef);
    }

    _Type  t;
};

// 線程過程: 長時間執行的 線程過程
// AddRef() 和 Release()必須線上程中成對調用
static DWORD WINAPI LongTimeThreadProc( LPVOID lpParam )
{
    ThreadParamT<CUserdata> *pthrParam = (ThreadParamT<CUserdata> *) lpParam;
   
    // 入口處立即增加引用計數
    pthrParam->AddRef();

    // 類比執行一個長時間的任務
    printf("LongTimeThreadProc::Do a long time job....../n");
    SleepEx(10000, 0);

    // 返回時必須減少引用計數
    pthrParam->Release();
   
    return 0;
}

int main()
{
    // 建立線程過程參數, 這個參數傳遞給線程之後, 生存期就由引用計數控制
    ThreadParamT<CUserdata> * thrParam = new ThreadParamT<CUserdata>();

    DWORD  dwThrId;   
    HANDLE hThread = CrtCreateThread(0, 0, LongTimeThreadProc, (LPVOID)thrParam, 0, &dwThrId);

    // 下面的代碼假設我們來不急等待線程執行結束
    // 此時, thrParam 的生存期有引用計數管理是適當的
    DWORD   dwRet = WaitForSingleObject(hThread, 5000);
    assert(dwRet==WAIT_TIMEOUT);
    CloseHandle(hThread);

    // 此時仍可訪問線程資料, 注意是否使用關鍵區保護
    printf("此時仍可訪問線程資料: %d/n", thrParam->t.m_data);

    // 此時釋放引用計數, 如果線程未結束, 則資料並未釋放
    thrParam->Release();

    SleepEx(6000, 0);

    printf("thrParam 已經不可用, 此時不可訪問線程資料: %d/n", thrParam->t.m_data);

    return 0;
}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.