如果我正確理解你的問題,我相信這可以在Windows中使用Win32函數GetCurrentThreadId()完成。 下面是它如何使用的一個快速和骯髒的例子。線程同步應該使用鎖對象來完成。
如果在要跟蹤線程的對象的每個成員函數的頂部創建一個CMyThreadTracker對象,_handle_vector
應包含使用您的對象的線程ID。
#include <process.h>
#include <windows.h>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
class CMyThreadTracker
{
vector<DWORD> & _handle_vector;
DWORD _h;
CRITICAL_SECTION &_CriticalSection;
public:
CMyThreadTracker(vector<DWORD> & handle_vector,CRITICAL_SECTION &crit):_handle_vector(handle_vector),_CriticalSection(crit)
{
EnterCriticalSection(&_CriticalSection);
_h = GetCurrentThreadId();
_handle_vector.push_back(_h);
printf("thread id %08x\n",_h);
LeaveCriticalSection(&_CriticalSection);
}
~CMyThreadTracker()
{
EnterCriticalSection(&_CriticalSection);
vector<DWORD>::iterator ee = remove_if(_handle_vector.begin(),_handle_vector.end(),bind2nd(equal_to<DWORD>(), _h));
_handle_vector.erase(ee,_handle_vector.end());
LeaveCriticalSection(&_CriticalSection);
}
};
class CMyObject
{
vector<DWORD> _handle_vector;
public:
void method1(CRITICAL_SECTION & CriticalSection)
{
CMyThreadTracker tt(_handle_vector,CriticalSection);
printf("method 1\n");
EnterCriticalSection(&CriticalSection);
for(int i=0;i<_handle_vector.size();++i)
{
printf(" this object is currently used by thread %08x\n",_handle_vector[i]);
}
LeaveCriticalSection(&CriticalSection);
}
};
CMyObject mo;
CRITICAL_SECTION CriticalSection;
unsigned __stdcall ThreadFunc(void* arg)
{
unsigned int sleep_time = *(unsigned int*)arg;
while (true)
{
Sleep(sleep_time);
mo.method1(CriticalSection);
}
_endthreadex(0);
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hThread;
unsigned int threadID;
if (!InitializeCriticalSectionAndSpinCount(&CriticalSection, 0x80000400))
return -1;
for(int i=0;i<5;++i)
{
unsigned int sleep_time = 1000 *(i+1);
hThread = (HANDLE)_beginthreadex(NULL, 0, &ThreadFunc, &sleep_time, 0, &threadID);
printf("creating thread %08x\n",threadID);
}
WaitForSingleObject(hThread, INFINITE);
return 0;
}
EDIT1: 如在評論中提及,參考分配可以被實現爲以下。一個向量可以容納引用你的對象的唯一線程ID。您可能還需要實現自定義賦值運算符來處理由不同線程複製的對象引用。
class MyClass
{
public:
static MyClass & Create()
{
static MyClass * p = new MyClass();
return *p;
}
static void Destroy(MyClass * p)
{
delete p;
}
private:
MyClass(){}
~MyClass(){};
};
class MyCreatorClass
{
MyClass & _my_obj;
public:
MyCreatorClass():_my_obj(MyClass::Create())
{
}
MyClass & GetObject()
{
//TODO:
// use GetCurrentThreadId to get thread id
// check if the id is already in the vector
// add this to a vector
return _my_obj;
}
~MyCreatorClass()
{
MyClass::Destroy(&_my_obj);
}
};
int _tmain(int argc, _TCHAR* argv[])
{
MyCreatorClass mcc;
MyClass &o1 = mcc.GetObject();
MyClass &o2 = mcc.GetObject();
return 0;
}
我認爲解決您的問題非常困難。這是因爲引用是指向另一個內存位置的內存或內存(+或多或少的額外內容)。因爲內存在線程之間共享,所以你不能分辨哪個線程擁有引用,只是因爲所有線程都「擁有」內存,它們都擁有引用。這並不意味着這是不可能的,但是由於技術基礎總是分享內容,所以很難做到。 – mmmmmmmm 2009-06-26 15:38:17
是的,我希望通過控制線程的創建方式,我可以以某種方式解決這個問題。我編輯了我的帖子,使這種可能性明確。 – 2009-06-26 15:45:41