2009-03-01 30 views
1

我有两个使用事件进行同步的线程。 在每个线程它们使用相同的电话:在C++中创建/打开事件并检查它们是否被触发

::CreateEvent(NULL,TRUE,FALSE,tcEventName) 

生产者线程是一个使呼叫第一,而消费者线程使最后调用,所以它在技术上开放,而不是创建该事件...我假设。

但是,当SetEvent的是所谓的生产者线程,相同的事件永远不会在消费者线程触发(我使用WaitForMultipleObjects的())

是否有一个工具,可以告诉我,如果该事件是实际上正确触发。

此外,当我在每个线程中调用CreateEvent()时,返回的句柄值对于每个值都是不同的...它们应该是相同的吗?

有没有更好的方法来做到这一点,以确保它能正常工作?

这是在Windows XP上使用Visual Studio 2005

编辑:我做了一些更多的检查,发现在生产者线程调用CreateEvent(第二个呼叫CreateEvent)设置LastError至183(ERROR_ALREADY_EXISTS) , 然而,CreateEvent仍然返回事件的句柄...什么给了?它如何错误已存在,但仍然返回句柄?还是应该这样做?

回答

1

根据MSDN文档CreateEvent

如果函数成功,返回值是一个句柄事件对象。如果指定的事件对象在函数调用之前存在,则该函数返回现有对象的句柄,并且GetLastError返回ERROR_ALREADY_EXISTS。

根据你的描述,我没有看到你在做什么的问题。我没有看到任何东西表明你在做错误的事情。不过,对于我来说,我通常使用CreateEvent()创建事件,然后将句柄传递给我想通过该事件发送信号的线程。但是你的方法没有任何技术上的错误。

你知道WaitForMultipleObjects()返回handles数组中第一个发信号的句柄的索引吧?例如,如果您的已命名事件是列表中的第二个事件,但绝大多数时间(例如,通过快速行为线程或手动重置事件发出信号,但从未重置),第一个句柄会发出信号,WaitForMultipleObjects ()将始终返回WAIT_OBJECT_0。换句话说,您的消费者线程将永远不会看到您的已命名事件发出信号,因为第一个句柄“始终”发送信号。如果是这种情况,请将您的指定事件放在列表中。

您不需要将WaitForMultipleObjects()的bWaitAll参数设置为TRUE,对吗?如果这样做,那么在函数返回之前,句柄数组中的所有句柄都有信号。

谁为您的指定事件调用了ResetEvent()?它应该是消费者。这不是偶然被某个第三方线程调用的,是吗?

这些只是一些事情要仔细检查。如果事件仍然不像您期望的那样运行,请用WaitForSingleObject()替换WaitForMultipleObjects()以查看您的命名事件是否正确地指示消费者线程。

希望这会有所帮助。

0

你的代码应该像你描述的那样工作。如果事件在您尝试创建时已经存在,您将获得现有事件的句柄。

每个线程的句柄是不同的,所以如果它们不同(它们应该是),你不必担心。

我建议你简化一下,看看事情是否按照你期望的方式工作。你使用WaitForMultipleObjects()的事实告诉我你还有其他的东西在继续。如果你认为它不起作用,请去掉其他东西,看看你是否可以搞清楚。

+0

查看更新的问题... – 2009-03-01 18:38:58

+0

http://www.google.com/search?q=createevent < - 第一个结果 – SoapBox 2009-03-01 20:18:22

1

如果你只在一个进程中使用多个线程,为什么不把事件句柄从一个传递到另一个呢?据我所知,创建的命名内核对象可在进程之间共享它们。

你也可以尝试使用OpenEvent函数打开已经创建的事件。这可能会提供一些想法。

0

在单个进程中,您只需调用一次CreateEvent并共享所有线程中返回的句柄。

此外,除非您希望外部进程通过OpenEvent访问事件,否则不需要命名该事件。实际上,如果您命名事件,则只有一个程序副本能够成功调用CreateEvent。

相关问题