在线请教,创建200个线程后,如何等待和判断线程是否完成?
听说WaitForMultipleObjects最多只能等待64个线程,不知该如何解决?
听说WaitForMultipleObjects最多只能等待64个线程,不知该如何解决?
解决方案 »
- 请问什么是图像的白化?
- Dialog下位图刷新问题
- 如何限制多线程读CListCtrl里的同一值,有没有管理线程的队列?或者多线程去读取队列,防止多线程读取同一个内容.
- 我自定义的一个按钮类怎么用到其他工程
- 怎样用DestroyWindow才能关闭画图程序呢?
- 碰到一个这种函数定义,不晓得是什么意思
- 誰來講一下 事件(Event) 和 消息 (Message) 之間的異同點!
- 高手啊!~请问如何将BMP图象序列化为二进制文件啊?用什么方法啊?
- 高手门能给个自定义资源exe的设置 到调用的自定义资源exe的操作?
- C/C++的思索 C++之父访谈录
- 《网际互联协议》--新做了一个东西,看有感兴趣的吗!
- 关于字符串替换的问题
WaitForMultiExpression
DWORD WINAPI WaitForMultipleExpressions(DWORD nExpObjects,
CONST HANDLE* phExpObjects, DWORD dwMilliseconds) { // Allocate a temporary array because we modify the passed array and
// we need to add a handle at the end for the hsemOnlyOne semaphore.
PHANDLE phExpObjectsTemp = (PHANDLE)
_alloca(sizeof(HANDLE) * (nExpObjects + 1));
CopyMemory(phExpObjectsTemp, phExpObjects, sizeof(HANDLE) * nExpObjects);
phExpObjectsTemp[nExpObjects] = NULL; // Put sentinel at end // Semaphore to guarantee that only one expression gets satisfied
HANDLE hsemOnlyOne = CreateSemaphore(NULL, 1, 1, NULL);
// Expression information: 1 per possible thread
EXPRESSION Expression[MAXIMUM_WAIT_OBJECTS]; DWORD dwExpNum = 0; // Current expression number
DWORD dwNumExps = 0; // Total number of expressions DWORD dwObjBegin = 0; // First index of a set
DWORD dwObjCur = 0; // Current index of object in a set DWORD dwThreadId, dwWaitRet = 0; // Array of thread handles for threads: 1 per expression
HANDLE ahThreads[MAXIMUM_WAIT_OBJECTS]; // Parse the callers handle list by initializing a structure for
// each expression and adding hsemOnlyOne to each expression.
while ((dwWaitRet != WAIT_FAILED) && (dwObjCur <= nExpObjects)) { // While no errors, and object handles are in the caller's list... // Find next expression (OR-expressions are separated by NULL handles)
while (phExpObjectsTemp[dwObjCur] != NULL)
dwObjCur++;
// Initialize Expression structure which an OR-thread waits on
phExpObjectsTemp[dwObjCur] = hsemOnlyOne;
Expression[dwNumExps].m_phExpObjects = &phExpObjectsTemp[dwObjBegin];
Expression[dwNumExps].m_nExpObjects = dwObjCur - dwObjBegin + 1; if (Expression[dwNumExps].m_nExpObjects > MAXIMUM_WAIT_OBJECTS) {
// Error: Too many handles in single expression
dwWaitRet = WAIT_FAILED;
SetLastError(ERROR_SECRET_TOO_LONG);
} // Advance to the next expression
dwObjBegin = ++dwObjCur;
if (++dwNumExps == MAXIMUM_WAIT_OBJECTS) {
// Error: Too many expressions
dwWaitRet = WAIT_FAILED;
SetLastError(ERROR_TOO_MANY_SECRETS);
}
} if (dwWaitRet != WAIT_FAILED) { // No errors occurred while parsing the handle list // Spawn thread to wait on each expression
for (dwExpNum = 0; dwExpNum < dwNumExps; dwExpNum++) { ahThreads[dwExpNum] = chBEGINTHREADEX(NULL,
1, // We only require a small stack
WFME_ThreadExpression, &Expression[dwExpNum],
0, &dwThreadId);
} // Wait for an expression to come TRUE or for a timeout
dwWaitRet = WaitForMultipleObjects(dwExpNum, ahThreads,
FALSE, dwMilliseconds); if (WAIT_TIMEOUT == dwWaitRet) { // We timed-out, check if any expressions were satisfied by
// checking the state of the hsemOnlyOne semaphore.
dwWaitRet = WaitForSingleObject(hsemOnlyOne, 0); if (WAIT_TIMEOUT == dwWaitRet) { // If the semaphore was not signaled, some thread expressions
// was satisfied; we need to determine which expression.
dwWaitRet = WaitForMultipleObjects(dwExpNum,
ahThreads, FALSE, INFINITE); } else { // No expression was satisfied and WaitForSingleObject just gave
// us the semaphore so we know that no expression can ever be
// satisfied now -- waiting for an expression has timed-out.
dwWaitRet = WAIT_TIMEOUT;
}
} // Break all the waiting expression threads out of their
// wait state so that they can terminate cleanly.
for (dwExpNum = 0; dwExpNum < dwNumExps; dwExpNum++) { if ((WAIT_TIMEOUT == dwWaitRet) ||
(dwExpNum != (dwWaitRet - WAIT_OBJECT_0))) { QueueUserAPC(WFME_ExpressionAPC, ahThreads[dwExpNum], 0);
}
}#ifdef _DEBUG
// In debug builds, wait for all of expression threads to terminate
// to make sure that we are forcing the threads to wake up.
// In non-debug builds, we'll assume that this works and
// not keep this thread waiting any longer.
WaitForMultipleObjects(dwExpNum, ahThreads, TRUE, INFINITE);
#endif // Close our handles to all the expression threads
for (dwExpNum = 0; dwExpNum < dwNumExps; dwExpNum++) {
CloseHandle(ahThreads[dwExpNum]);
}
} // error occurred while parsing CloseHandle(hsemOnlyOne);
return(dwWaitRet);
}
while (Count > 0)
{
Sleep(50);
}
在等待,当扫描数小于5000时基本没问题,(就是有时时间太长)
当大于5000时,就出问题,一直等不到?而且不太稳定,一时好,一时就出错了?
不知该怎么解决?
while (Count > 0)
{
Sleep(50);
}
在等待,当扫描数小于5000时基本没问题,(就是有时时间太长)
当大于5000时,就出问题,一直等不到?而且不太稳定,一时好,一时就出错了?
不知该怎么解决?
另外 Sleep(50);太长了,Sleep(10)足够了。
for(int i=0;i<200;i++)
{
ss[i].i=i;
ss[i].start();
}for(i=0;i<200;i++)
ss[i].waitCurThread();
public Thread
{
public:
int i;
virtual void run()
{
printf("%d\r\n",i);
}
};
#pragma warning(disable:4800)
#include <process.h>class Thread
{
private:
HANDLE hThread; //当前线程句柄
unsigned ThreadId; //当前线程ID
public:
static unsigned __stdcall startThread(void *threadObject)
{
if(threadObject==NULL)
return E_INVALIDARG;
Thread *curThread=(Thread *)threadObject;
curThread->Pre();
curThread->run();
curThread->End();
return S_OK;
} Thread(void):hThread(NULL),ThreadId(0){} virtual ~Thread(void)
{
if(!isAlive())
{
CloseHandle(hThread);
ThreadId=0;
}
else
{
TerminateThread(hThread,0);
CloseHandle(hThread);
ThreadId=0;
}
}
virtual void stop() {return;}
//线程开始准备
virtual void Pre() {return;}
//线程处理逻辑
virtual void run()=0;
//线程终止处理
virtual void End() {return;}
//判断线程是否启动
inline bool Thread::isAlive()
{
if(hThread==NULL) return false;
DWORD exitCode;
if(GetExitCodeThread(hThread,&exitCode))
{
if(exitCode==STILL_ACTIVE)
return true;
}
return false;
}
//启动并开始线程
bool start()
{
DWORD exitCode;
if(GetExitCodeThread(hThread,&exitCode))
{
if(exitCode==STILL_ACTIVE)
return false;
}
CloseHandle(hThread);
hThread=(HANDLE)_beginthreadex(NULL,0,Thread::startThread,(void *)this,0,&ThreadId);
return hThread!=0;
} //中断该线程
inline bool terminate()
{
if(!isAlive())
return true;
else
return (bool)TerminateThread(hThread,0);
}
//启动并挂起程序
bool startsuspend()
{
//如果该线程以经启动,直接返回
if(isAlive())
return false;
CloseHandle(hThread);
hThread=(HANDLE)_beginthreadex(NULL,0,Thread::startThread,(void *)this,CREATE_SUSPENDED,&ThreadId);
return hThread!=0;
} //换醒线程
inline bool resume(){return ResumeThread(hThread)!=-1;}
//等待当前线程完
inline void waitCurThread(){WaitForSingleObject(hThread,INFINITE);}
inline void waitCurThread(DWORD dwMilliseconds){WaitForSingleObject(hThread,dwMilliseconds);}
inline unsigned getThreadId() {ASSERT(ThreadId!=NULL);return ThreadId;}
inline HANDLE getThreadHandle() {ASSERT(hThread!=NULL);return hThread;}
};
做个记数器 注意是Critical Section