简体   繁体   English

EventWaitHandle-多个线程=行为不一致

[英]EventWaitHandle - multiple threads = inconsistent behaviour

I am trying to setup some comms with a device where you can send a command and receive a response. 我正在尝试与设备建立一些通信,您可以在其中发送命令并接收响应。 I do however want to ensure that I control a timeout flag to prevent indefinite wait times. 但是,我确实想确保控制超时标志以防止不确定的等待时间。

I did something like this: 我做了这样的事情:

private volatile EventWaitHandle _signal;

public void Send()
{
    // Do something

    _signal.WaitOne(30000);

    // Continue with something else

    _signal.Reset();
}

public void Receive() 
{
    _signal.Set();
}

My question is, if I have multiple threads (let's say 2 for this example) that can access the Send method and the following scenario: 我的问题是,如果我有多个线程(在本示例中为2)可以访问Send方法和以下情况:

Thread A: 线程A:

// Sends a "listen" command, but no response is received 
Send();

Thread B: 线程B:

// Sends a "cancel" command and response (success) is received
Send();

I get inconsistent results, ie sometimes both threads continue when I get a response for the second command (cancel) which I can understand, but sometimes the first thread will hit the 30000ms timeout - which I cannot explain. 我得到不一致的结果,即有时当我能理解的第二个命令(取消)得到响应时,两个线程都继续,但有时第一个线程将达到30000ms超时-我无法解释。

Any advice as to what I am missing and/or doing wrong? 关于我缺少和/或做错什么的任何建议吗?

An EventWaitHandle is not the appropriate synchronization object here. EventWaitHandle在此处不是适当的同步对象。 You require mutual exclusion so that only one thread can be in a state where it sent a command and is waiting for the response. 您需要互斥,以便只有一个线程可以处于发送命令并等待响应的状态。 In other words, threads must strictly take their turn to talk to the device. 换句话说,线程必须严格轮流与设备通信。

A ManualResetEvent doesn't give you that guarantee, as soon as you call Set() then all the threads that are blocking on the WaitOne() call will be unblocked. ManualResetEvent不能保证,一旦调用Set(), 所有在WaitOne()调用中阻塞的线程都将被解除阻塞。 If that's more than one then your program will malfunction when two or more threads try to send a command at the same time. 如果不止一个,那么当两个或多个线程尝试同时发送命令时,您的程序将出现故障。

A Mutex provides MUTual EXclusion. 互斥锁提供互斥。 That's how it got its name. 这就是它的名字。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM