Multithreading C++/CLI UdpClient多线程池

Multithreading C++/CLI UdpClient多线程池,multithreading,c++-cli,udpclient,Multithreading,C++ Cli,Udpclient,我首先说这是我的第一个多线程软件,所以要有礼貌:) 我有一个用C++/CLI编写的多线程应用程序,它使用UdpClient池从外部硬件读/写 基本上,有三个线程:一个接收线程,用于管理从外部硬件传入的消息的接收并将其放入解析队列;一个解析线程,用于检查接收消息的正确性并生成适当的响应,并将其放入发送队列,以及发送线程,其连续检查发送队列以将排队的消息发送到外部硬件 至于UdpClient,我使用其中两个:接收客户端接收传入消息,发送客户端发送响应:这是因为外部硬件可以在运行时更改其IP地址,因此

我首先说这是我的第一个多线程软件,所以要有礼貌:)

我有一个用C++/CLI编写的多线程应用程序,它使用UdpClient池从外部硬件读/写

基本上,有三个线程:一个接收线程,用于管理从外部硬件传入的消息的接收并将其放入解析队列;一个解析线程,用于检查接收消息的正确性并生成适当的响应,并将其放入发送队列,以及发送线程,其连续检查发送队列以将排队的消息发送到外部硬件

至于UdpClient,我使用其中两个:接收客户端接收传入消息,发送客户端发送响应:这是因为外部硬件可以在运行时更改其IP地址,因此接收UdpClient必须侦听任何IP地址,而发送客户端应将数据报发送到外部硬件的特定IP地址。此外,接收客户端具有允许控制外部硬件的连接状态的超时值

这里我展示了接收线程的一些示例代码:

// Receiving thread
UdpClient^ receivingClient = gcnew UdpClient(IPAddress::Any, 30303);
// Set a timeout
receivingClient->Client->ReceiveTimeout = 3000;
// Iteratively receive on IP::Any and 30303
while(true)    
{
    try
    {
        array<Byte>^ recMessage = receivingClient->Receive();
        // Put the message in the parsing queue, which is a global object
        parQueue->Enqueue(recMessage);
    }
    catch (SocketException^ ex)
    {
        // Handle timeout exception
    }
}
while(true)
{
     if(parQueue->Count > 0)
     {
         // Method that parse message and puts it in the sending queue
         ParseMessage(parQueue->Dequeue());
     }
}
UdpClient^ sendingClient = gcnew UdpClient(ExternalHardwareIp, 30303);
while(true)
{
    if(senQueue->Count > 0)
    {
        sendingClient->Send(senQueue->Dequeue());
    }
}
最后,这里是发送线程的一些示例代码:

// Receiving thread
UdpClient^ receivingClient = gcnew UdpClient(IPAddress::Any, 30303);
// Set a timeout
receivingClient->Client->ReceiveTimeout = 3000;
// Iteratively receive on IP::Any and 30303
while(true)    
{
    try
    {
        array<Byte>^ recMessage = receivingClient->Receive();
        // Put the message in the parsing queue, which is a global object
        parQueue->Enqueue(recMessage);
    }
    catch (SocketException^ ex)
    {
        // Handle timeout exception
    }
}
while(true)
{
     if(parQueue->Count > 0)
     {
         // Method that parse message and puts it in the sending queue
         ParseMessage(parQueue->Dequeue());
     }
}
UdpClient^ sendingClient = gcnew UdpClient(ExternalHardwareIp, 30303);
while(true)
{
    if(senQueue->Count > 0)
    {
        sendingClient->Send(senQueue->Dequeue());
    }
}
现在,我认为这种方法有几个问题,因为发送线程上的发送操作似乎阻塞了整个应用程序,阻止了接收线程从外部硬件接收任何消息,并给我带来了一些麻烦


提前感谢您的提示。

此代码存在很多问题。以极快的速度,您的队列不是线程安全的,需要锁定,您的传输线程消耗了100%的内核,完成的工作非常少,您没有好的方法让程序关闭,没有有意义的方法来处理超时,然后再试一次,UDP不是面向连接的。通过不创建自己的线程来获得成功。使用UdpClient.Send()可以利用操作系统提供的缓冲。和BeginReceive()将线程的危险降至最低。非常感谢您的建议;我知道我必须说明这不是真正的代码,而是一种简化。但是,我使用ConcurrentQueue,因为根据MSDN它是线程安全的,程序的关闭实际上是在实际代码中管理的,并且由于超时而导致的SocketException被处理。老实说,我正在考虑两种处理线程危险的方法:同时使用BeginSend和BeginReceive,或者切换到底层套接字。