在线请教,创建200个线程后,如何等待和判断线程是否完成?

virword 2005-04-06 09:05:13
在线请教,创建200个线程后,如何等待和判断线程是否完成?
听说WaitForMultipleObjects最多只能等待64个线程,不知该如何解决?
...全文
367 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
virword 2005-06-28
  • 打赏
  • 举报
回复
bb
virword 2005-06-26
  • 打赏
  • 举报
回复
ss
virword 2005-04-07
  • 打赏
  • 举报
回复
已解决,送分。

Totogecy() ( ) 信誉:100 2005-04-06 16:51:00 得分: 0
做个记数器 注意是Critical Section


DentistryDoctor 2005-04-06
  • 打赏
  • 举报
回复
// Function to wait on mutiple Boolean expressions
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);
}
DentistryDoctor 2005-04-06
  • 打赏
  • 举报
回复
Windows核心编程一书中讲得有一个中
WaitForMultiExpression
yinzhaohui 2005-04-06
  • 打赏
  • 举报
回复
#pragma once
#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;}
};
yinzhaohui 2005-04-06
  • 打赏
  • 举报
回复
class TestThread:
public Thread
{
public:
int i;
virtual void run()
{
printf("%d\r\n",i);
}
};
yinzhaohui 2005-04-06
  • 打赏
  • 举报
回复
TestThread ss[200];
for(int i=0;i<200;i++)
{
ss[i].i=i;
ss[i].start();
}

for(i=0;i<200;i++)
ss[i].waitCurThread();
virword 2005-04-06
  • 打赏
  • 举报
回复
原因已经早到一半了,在测试
xift_2008 2005-04-06
  • 打赏
  • 举报
回复
200个线程已经很多了,呵呵,看能否再精简一些,线程越多越不好维护!
另外 Sleep(50);太长了,Sleep(10)足够了。
virword 2005-04-06
  • 打赏
  • 举报
回复
我做了计数器啦,我用
while (Count > 0)
{
Sleep(50);
}
在等待,当扫描数小于5000时基本没问题,(就是有时时间太长)
当大于5000时,就出问题,一直等不到?而且不太稳定,一时好,一时就出错了?
不知该怎么解决?
virword 2005-04-06
  • 打赏
  • 举报
回复
我做了计数器啦,我用
while (Count > 0)
{
Sleep(50);
}
在等待,当扫描数小于5000时基本没问题,(就是有时时间太长)
当大于5000时,就出问题,一直等不到?而且不太稳定,一时好,一时就出错了?
不知该怎么解决?
Totogecy 2005-04-06
  • 打赏
  • 举报
回复
做个记数器 注意是Critical Section
Daniel22_cn 2005-04-06
  • 打赏
  • 举报
回复
做个计数器有问题吗。。定义同步变量,每次只允许一个线程将计数器+1,主线程等待计数器为0时再退出。

Windows核心对象的引用不就是使用这个方式实现的吗?
北漂17载 2005-04-06
  • 打赏
  • 举报
回复
有意思 mark
jemmy 2005-04-06
  • 打赏
  • 举报
回复
关注
virword 2005-04-06
  • 打赏
  • 举报
回复
是不是分太少了,我再开贴,加分
virword 2005-04-06
  • 打赏
  • 举报
回复
不是,我开200个线程,扫10000个端口,,线程就没法正常退出。不知怎么办了?
xift_2008 2005-04-06
  • 打赏
  • 举报
回复
开太多线程是很难控制的,扫描数目是10000,你不会开10000个线程吧?
virword 2005-04-06
  • 打赏
  • 举报
回复
不行啊,当扫描数目一大,比如10000个时,等线程退出,经常会出错。有时就等不到线程退出?
加载更多回复(4)

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧