//Get all threads std::deque<DWORD> dqThreads; HANDLE hThreadSnap = NULL; BOOL bRet = FALSE; THREAD_INFORMATION_EX tie; DWORD dwThisThread = ::GetCurrentThreadId(); // used for not killing ourself // Take a snapshot of all threads currently in the system. DWORD dwProcessID=GetCurrentProcessId(); hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, dwProcessID); if (hThreadSnap == INVALID_HANDLE_VALUE) return false; // Fill in the size of the structure before using it. tie.te32.dwSize = sizeof(THREADENTRY32); // Walk the thread snapshot to find all threads of the process. // If the thread belongs to the process, add its information // to the display list. if (Thread32First(hThreadSnap, &tie.te32)) { do { if (tie.te32.th32OwnerProcessID == dwProcessID) { dqThreads.push_back(tie.te32.th32ThreadID); ZeroMemory(&tie, sizeof(THREAD_INFORMATION_EX)); tie.te32.dwSize = sizeof(THREADENTRY32); } } while (Thread32Next(hThreadSnap, &tie.te32)); bRet = TRUE; } //else // return false; // could not walk the list of threads CloseHandle (hThreadSnap); // HANDLE ThreadArray[64]; ... DWORD dwRet=WaitForMultipleObjects(ThreadCount,ThreadArray, TRUE, 5000);
semaphore WINDOWS高级编程里面有一个地方专门讨论了这个
//Get all threads std::deque <DWORD > dqThreads; HANDLE hThreadSnap = NULL; BOOL bRet = FALSE; THREAD_INFORMATION_EX tie; DWORD dwThisThread = ::GetCurrentThreadId(); // used for not killing ourself
// Take a snapshot of all threads currently in the system. DWORD dwProcessID=GetCurrentProcessId(); hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, dwProcessID); if (hThreadSnap == INVALID_HANDLE_VALUE) return false; // Fill in the size of the structure before using it. tie.te32.dwSize = sizeof(THREADENTRY32); // Walk the thread snapshot to find all threads of the process. // If the thread belongs to the process, add its information // to the display list. if (Thread32First(hThreadSnap, &tie.te32)) { do { if (tie.te32.th32OwnerProcessID == dwProcessID) { dqThreads.push_back(tie.te32.th32ThreadID); ZeroMemory(&tie, sizeof(THREAD_INFORMATION_EX)); tie.te32.dwSize = sizeof(THREADENTRY32); } } while (Thread32Next(hThreadSnap, &tie.te32)); bRet = TRUE; } //else // return false; // could not walk the list of threads CloseHandle (hThreadSnap); // HANDLE ThreadArray[64]; ... DWORD dwRet=WaitForMultipleObjects(ThreadCount,ThreadArray, TRUE, 5000);
std::deque<DWORD> dqThreads;
HANDLE hThreadSnap = NULL;
BOOL bRet = FALSE;
THREAD_INFORMATION_EX tie;
DWORD dwThisThread = ::GetCurrentThreadId(); // used for not killing ourself // Take a snapshot of all threads currently in the system.
DWORD dwProcessID=GetCurrentProcessId();
hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, dwProcessID);
if (hThreadSnap == INVALID_HANDLE_VALUE)
return false;
// Fill in the size of the structure before using it.
tie.te32.dwSize = sizeof(THREADENTRY32);
// Walk the thread snapshot to find all threads of the process.
// If the thread belongs to the process, add its information
// to the display list.
if (Thread32First(hThreadSnap, &tie.te32))
{
do
{
if (tie.te32.th32OwnerProcessID == dwProcessID)
{
dqThreads.push_back(tie.te32.th32ThreadID);
ZeroMemory(&tie, sizeof(THREAD_INFORMATION_EX));
tie.te32.dwSize = sizeof(THREADENTRY32);
}
}
while (Thread32Next(hThreadSnap, &tie.te32));
bRet = TRUE;
}
//else
// return false; // could not walk the list of threads
CloseHandle (hThreadSnap);
//
HANDLE ThreadArray[64];
...
DWORD dwRet=WaitForMultipleObjects(ThreadCount,ThreadArray, TRUE, 5000);
WINDOWS高级编程里面有一个地方专门讨论了这个
std::deque <DWORD > dqThreads;
HANDLE hThreadSnap = NULL;
BOOL bRet = FALSE;
THREAD_INFORMATION_EX tie;
DWORD dwThisThread = ::GetCurrentThreadId(); // used for not killing ourself
// Take a snapshot of all threads currently in the system.
DWORD dwProcessID=GetCurrentProcessId();
hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, dwProcessID);
if (hThreadSnap == INVALID_HANDLE_VALUE)
return false;
// Fill in the size of the structure before using it.
tie.te32.dwSize = sizeof(THREADENTRY32);
// Walk the thread snapshot to find all threads of the process.
// If the thread belongs to the process, add its information
// to the display list.
if (Thread32First(hThreadSnap, &tie.te32))
{
do
{
if (tie.te32.th32OwnerProcessID == dwProcessID)
{
dqThreads.push_back(tie.te32.th32ThreadID);
ZeroMemory(&tie, sizeof(THREAD_INFORMATION_EX));
tie.te32.dwSize = sizeof(THREADENTRY32);
}
}
while (Thread32Next(hThreadSnap, &tie.te32));
bRet = TRUE;
}
//else
// return false; // could not walk the list of threads
CloseHandle (hThreadSnap);
//
HANDLE ThreadArray[64];
...
DWORD dwRet=WaitForMultipleObjects(ThreadCount,ThreadArray, TRUE, 5000);
WaitForSingleObject(hThread,INFINITE)等待线程退出,
有时候会一直等待下去。
这是为什么呢。请指教。
WIN32 API提供了一组能使线程阻塞其自身执行的等待函数,这些函数只有在作为其参数的一个或多个同步对象产生信号时才返回,在超过规定的等待时间后,不管有无信号,函数都会返回,在等待函数未返回时,线程处于等待状态,此时线程只消耗很少的CPU时间,使用等待函数即可以保证线程同步,又可以提高效率,常用的是:
DWORD WaitForSingleObject,同时监测多个同步对象函数:WaitForMultipleObjects共有三种同步对象:事件、mutex和信号灯(semaphore,也就是你们上面所说的)事件对象是最简单的同步对象,该对象是用CreateEvent函数建立的,SetEvent可以把事件对象设置为有信号状态 ResetEvent把事件对象设置为无信号状态mutex对象的状态在它不被任何线程拥有时是有信号的,而当它被拥有时则是无信号的,该对象适合用来协调多线程对共享资源的互斥访问该线程用CreateMutex来建立,ReleaseMutex释放,如果线程终止而不释放,则认为被废弃信号灯对象维护一个从0开始的计数,线程用CreateSemaphore函数来建立信号灯对象,别的进程可以用OpenSemaphore函数打开指定名字的信号灯句柄,一般把信号灯初始计数设置为最大值,每当信号灯有信号使等待函数返回时,信号灯计数就会减1,而调用ReleaseSemaphore可以增加信号灯的计数,数值越小表明访问共享资源的程序越多。
WaitForMultipleObject()函数等待所有的线程返回!
另外就是WaitForMultipleObject()有64个的限制,我觉得可以使用event+ interlock的那2个函数解决。
线程退出时interlockdec... 发送 event,主线程收到event后读取计数。