想出了这么一个算法,屡试不爽,却不知是否真可行
定义了一个类T:
class T
{
DWORD threadID;
int threadDeep;
public:
T():threadID(NULL),threadDeep(0){}
void Wait();
void End();
}
void T::Wait()
{
DWORD id = ::GetCurrentThreadId();
if(threadID==id)
{
++threadDeep;
return;
}
START:;
while(threadID)::Sleep(0);
threadID = id;
::Sleep(0);//关键
if(threadID!=id)goto START;
}
void T::End()
{
if(::GetCurrentThreadId()==threadID)
{
if(--threadDeep < 0)
{
threadID = NULL;
threadDeep = 0;
}
}
}
T t;
t.Wait();
DoSomething();//该算法能否保证在同一时间只有一个线程执行此语句?
t.End();
void T::Wait()
{
DWORD id = ::GetCurrentThreadId();
if(threadID==id)
{
++threadDeep;
return;
}
START:;
while(threadID)::Sleep(0);
// 线程1、2同时运行到这里
threadID = id;
::Sleep(0);//关键
if(threadID!=id)goto START;
}
void T::Wait()
{
DWORD id = ::GetCurrentThreadId();
if(threadID==id)
{
++threadDeep;
return;
}
START:;
while(threadID)::Sleep(0);
// 线程2暂停在这里
threadID = id;
::Sleep(0);//关键
if(threadID!=id)goto START;
// 线程1运行到这里,已经返回了
}
volate T* pInst = 0;
T* GetInstance()
{
if (pInst == NULL)
{
lock();
if (pInst == NULL)
vpInst = new T;
unlock();
}
return pInst;
}
#include <iostream>
#include <windows.h>
#include <process.h>
#include <assert.h>
using namespace std;
class T
{
DWORD threadID;
int threadDeep;
public:
T():threadID(NULL),threadDeep(0){}
void Wait();
void End();
};
void T::Wait()
{
DWORD id = ::GetCurrentThreadId();
if(threadID==id)
{
++threadDeep;
return;
}
START:;
while(threadID)::Sleep(0);
::Sleep(1000); //增加::Sleep(1000)
threadID = id;
::Sleep(0);//关键
if(threadID!=id)goto START;
::Sleep(1000);//增加::Sleep(1000)
}
void T::End()
{
if(::GetCurrentThreadId()==threadID)
{
if(--threadDeep < 0)
{
threadID = NULL;
threadDeep = 0;
}
}
}
T t;
unsigned int __stdcall Fn(void *pArguments)
{
t.Wait();
cout<<"begin"<<endl;
Sleep(10000);
cout<<"end"<<endl;
t.End();
return 0;
}
#define THREAD_COUNT 50
int main()
{
HANDLE handles[THREAD_COUNT] = { NULL };
for (int i = 0; i < THREAD_COUNT; i++)
{
unsigned int tid = 0;
handles[i] =
(HANDLE)_beginthreadex(0, 0, &Fn, 0, 0, &tid);
assert(handles[i]);
}
for (int i = 0; i < THREAD_COUNT; i++)
{
::WaitForSingleObject(handles[i], INFINITE);
}
system("pause");
return 0;
}
START:;
while(threadID)::Sleep(0);
threadID = id;
::Sleep(0);//关键
if(threadID!=id)goto START;
[解决办法]
细节方面还有这个
void T::End()
{
if(::GetCurrentThreadId()==threadID)
{
if(--threadDeep < 0)
{
//这两句顺序交换
threadID = NULL;
threadDeep = 0;
}
}
}
START:;
while(threadID)::Sleep(0);
threadID = id;
::Sleep(0);//关键
if(threadID!=id)goto START;