多线程中WaitForSingleObject函数…

当多个线程调用WaitForSingleObject函数等待一个信号的时候,一旦这个信号返回,那么这几个线程怎么调试实际上是由操作系统决定的,可以说是随机的,或者说是不可预测的。可以通过下面这段代码来验证:
#include
#include

#define THREADCOUNT 4 

HANDLE ghWriteEvent;
HANDLE ghThreads[THREADCOUNT];

DWORD WINAPI ThreadProc(LPVOID);

void CreateEventsAndThreads(void)
{
int i;
DWORD dwThreadID;

// Create a manual-reset event object. The write thread sets this
// object to the signaled state when it finishes writing to a 
// shared buffer. 

ghWriteEvent = CreateEvent(
NULL,               // default security attributes
TRUE,               // manual-reset event
FALSE,              // initial state is nonsignaled
TEXT("WriteEvent")  // object name
);

if (ghWriteEvent == NULL)
{
printf("CreateEvent failed (%d)\n", GetLastError());
return;
}

// Create multiple threads to read from the buffer.

for (i = 0; i < THREADCOUNT; i++)
{
// TODO: More complex scenarios may require use of a parameter
//   to the thread procedure, such as an event per thread to  
//   be used for synchronization.
ghThreads[i] = CreateThread(
NULL,              // default security
0,                 // default stack size
ThreadProc,        // name of the thread function
NULL,              // no thread parameters
0,                 // default startup flags
&dwThreadID);

if (ghThreads[i] == NULL)
{
printf("CreateThread failed (%d)\n", GetLastError());
return;
}
else{
printf("Thread %d created.\n", dwThreadID);
}
}
}

void WriteToBuffer(VOID)
{
// TODO: Write to the shared buffer.

printf("Main thread writing to the shared buffer...\n");

// Set ghWriteEvent to signaled

if (!SetEvent(ghWriteEvent))
{
printf("SetEvent failed (%d)\n", GetLastError());
return;
}
}

void CloseEvents()
{
// Close all event handles (currently, only one global handle).

CloseHandle(ghWriteEvent);
}

int main(void)
{
DWORD dwWaitResult;

// TODO: Create the shared buffer

// Create events and THREADCOUNT threads to read from the buffer

CreateEventsAndThreads();

// At this point, the reader threads have started and are most
// likely waiting for the global event to be signaled. However, 
// it is safe to write to the buffer because the event is a 
// manual-reset event.

WriteToBuffer();

printf("Main thread waiting for threads to exit...\n");

// The handle for each thread is signaled when the thread is
// terminated.
dwWaitResult = WaitForMultipleObjects(
THREADCOUNT,   // number of handles in array
ghThreads,     // array of thread handles
TRUE,          // wait until all are signaled
INFINITE);

switch (dwWaitResult)
{
// All thread objects were signaled
case WAIT_OBJECT_0:
printf("All threads ended, cleaning up for application exit...\n");
break;

// An error occurred
default:
printf("WaitForMultipleObjects failed (%d)\n", GetLastError());
return 1;
}

// Close the events to clean up

CloseEvents();

return 0;
}

DWORD WINAPI ThreadProc(LPVOID lpParam)
{
// lpParam not used in this example.
UNREFERENCED_PARAMETER(lpParam);

DWORD dwWaitResult;

printf("Thread %d waiting for write event...\n", GetCurrentThreadId());

dwWaitResult = WaitForSingleObject(
ghWriteEvent, // event handle
INFINITE);    // indefinite wait

switch (dwWaitResult)
{
// Event object was signaled
case WAIT_OBJECT_0:
//
// TODO: Read from the shared buffer
//
printf("Thread %d reading from buffer\n",
GetCurrentThreadId());
break;

// An error occurred
default:
printf("Wait error (%d)\n", GetLastError());
return 0;
}

// Now that we are done reading the buffer, we could use another
// event to signal that this thread is no longer reading. This
// example simply uses the thread handle for synchronization (the
// handle is signaled when the thread terminates.)

printf("Thread %d exiting\n", GetCurrentThreadId());

printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
printf("Thread %d exiting\n", GetCurrentThreadId());
return 1;
}
这段代码来自visual studio的帮助文档,我稍微修改了一下(加了些printf),使得我们可以从中看出点东西。运行结果如下,可以看出确实是随机的
Thread 4968 created.
Thread 4968 waiting for write event...
Thread 6444 created.
Thread 2296 created.
Thread 4400 created.
Main thread writing to the shared buffer...
Main thread waiting for threads to exit...
Thread 6444 waiting for write event...
Thread 4968 reading from buffer
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 6444 reading from buffer
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 6444 exiting
Thread 4400 waiting for write event...
Thread 4400 reading from buffer
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4400 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 2296 waiting for write event...
Thread 2296 reading from buffer
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 2296 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
Thread 4968 exiting
All threads ended, cleaning up for application exit...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值