Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 异步C++;插座_C++_Multithreading_Sockets_Asynchronous - Fatal编程技术网

C++ 异步C++;插座

C++ 异步C++;插座,c++,multithreading,sockets,asynchronous,C++,Multithreading,Sockets,Asynchronous,我正在尝试编写一个异步服务器来同时处理多个用户。服务器站在主线程中侦听接收数据,在接收数据的同一线程中(大型映像),并创建一个任务来处理该数据,然后将该数据发送到线程池,服务器本身侦听下一个映像。以下是代码(句柄包含在另一个线程上执行的数据处理): while(true){ cv::Mat data=ReceiveImage(); m_Pool.AddTask([=])可变{ 句柄(std::move(data)); }); } cv::Mat UDPServer::ReceiveImage()

我正在尝试编写一个异步服务器来同时处理多个用户。服务器站在主线程中侦听接收数据,在接收数据的同一线程中(大型映像),并创建一个任务来处理该数据,然后将该数据发送到线程池,服务器本身侦听下一个映像。以下是代码(句柄包含在另一个线程上执行的数据处理):

while(true){
cv::Mat data=ReceiveImage();
m_Pool.AddTask([=])可变{
句柄(std::move(data));
});
}
cv::Mat UDPServer::ReceiveImage()常量{
...
试一试{
for(int i=0;i
这种方法存在一个问题:当接受一个用户的数据时,另一个用户可以发送他的数据,而这些数据不会被接受

一种可能的解决方案是在不同的线程上接受数据。为此,我只希望在主线程中接收数据已到达的信号,并将它们传输到另一个线程以接收数据并将其发送到线程池。类似MPI中的探针


如何在C++套接字上实现这一点?我试图在互联网上找到它,但没有结果。或者有人有更好的解决方案吗?

TCP套接字就是这样工作的。有一个侦听套接字,称为P,还有一个实际的通信套接字,称为Q。系统调用执行以下操作:

Q = accept(P, ...); // there are other parameters 
                    // which are not important here
只要
accept
返回,就可以在Q上启动异步任务,并在p上继续侦听。这两个作业不会相互干扰。如果出现了另一个请求,为什么您仍在费力地处理Q,
accept
将只返回另一个Q,用于另一个异步任务


由于没有持久连接,所以整个想法对于UDP来说并没有那么好的效果。每个数据包都是自己的通信会话。从套接字异步读取数据包没有多大意义。读取是一种原子操作,数据包足够短。您可以启动一个异步任务来处理每个数据包的数据,这没有错。您可以尝试通过在套接字上轮询并启动异步任务来实现异步读取,该任务在数据准备好后立即读取数据,但这不会真正简化或加快任何操作。

您可以看看boost asio或Qt::network,两者都可以。您的问题是在循环时,
ReceiveImage
处的循环,你正在阻塞线程。正确的方法是将部分数据放入缓冲区,并使用轮询功能在不同的客户端之间循环(
poll
select
epoll
kqueue
,等等)。另一个问题是,在没有任何数据丢失保护的情况下,对流数据使用UDP套接字。TCP将是一个更好的选择,除非你去硬核和写你自己的丢包检测和逻辑。是的,我知道,但我的任务是写在C++ SoCKTCP上有硬件优化支持的网卡。我建议避免使用UDP,除非每条消息的长度小于1200字节,并且可以接受消息丢失和重新排序。这就是UDP更快的原因,它没有订单交付保证。UDP数据包可能无序到达、多次到达或根本不到达。另外,
poll
通常比
select
更好。对于超过1000个客户端,切勿使用
select
epoll
kqueue
都被认为更快,但这实际上取决于您如何使用它们以及套接字的活动程度。但是在UDP中该怎么做,在UDP中,不使用
accept
建立持久连接?@Egor祝您在UDP中编写类似ReceiveImage的内容好运。您最终将很糟糕地重新实现TCP。你为什么要那样?UDP最适用于数据包中的短消息。谢谢您的帮助。我来看看TCP的代词“谢谢,我终于明白你的意思了。”。听起来合乎逻辑,我会试试看!
Q = accept(P, ...); // there are other parameters 
                    // which are not important here