Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.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
Multithreading WSAsend到多线程iocp服务器中所有连接的套接字_Multithreading_Sockets_Iocp - Fatal编程技术网

Multithreading WSAsend到多线程iocp服务器中所有连接的套接字

Multithreading WSAsend到多线程iocp服务器中所有连接的套接字,multithreading,sockets,iocp,Multithreading,Sockets,Iocp,我在IOCP服务器上工作(重叠I/O,4个线程,CreateIoCompletionPort,GetQueuedCompletionStatus,WSASend等)。我还为每个异步I/O操作创建了一个自动重置事件,并将句柄放在重叠结构中 问题是:如何正确地将缓冲区发送到所有连接的套接字?每个套接字都存储在上下文信息结构的链接列表中 我不确定下面的方法是否可行 ... DWORD WINAPI WorkerThread() { // 1 of 4 workthread ... GetQueuedC

我在IOCP服务器上工作(重叠I/O,4个线程,
CreateIoCompletionPort
GetQueuedCompletionStatus
WSASend
等)。我还为每个异步I/O操作创建了一个自动重置事件,并将句柄放在重叠结构中

问题是:如何正确地将缓冲区发送到所有连接的套接字?每个套接字都存储在上下文信息结构的链接列表中

我不确定下面的方法是否可行

...
DWORD WINAPI WorkerThread() { // 1 of 4 workthread
...
GetQueuedCompletionStatus(...);
...
PPER_SOCKET_CONTEXT  pTmp1, pTmp2;
pTmp1 = g_pCtxtList; // start of linked list with sockets
EnterCriticalSection(&g_CriticalSection);
while( pTmp1 ) 
{  
pTmp2 = pTmp1->pCtxtBack;
         WaitForSingleObject(pTmp1->pIOContext->Overlapped.hEvent,infinite);                
          // if there is any pending wsasend on this socket,wait to completed, so
          // we can post another wsasend using the same overlapped structure
          // and buffer
           WSASend(pTmp1->Socket,...,&(pTmp1->pIOContext->Overlapped), NULL);
       pTmp1 = pTmp2;
 }
LeaveCriticalSection(&g_CriticalSection);
...
}
如果另一个线程同时尝试执行相同的工作,会发生什么情况?
在所有线程中使用GQCS和waits函数是个好主意吗?
如果您对多线程iocp服务器中的所有客户端提供有关wsasends的任何线索,我们将不胜感激。

thx

我不确定我是否理解其中的一些内容。IOCP通常不在OVL结构中使用hEvent字段。I/O完成通过将完成消息排入“完成端口”(即队列)来发出信号。您似乎正在使用hEvent字段来管理单个发送数据缓冲区和OVL块,以获得一些“不寻常”的额外信号

显然,我不知道你文章的全部内容,但在我看来,你在tx端为自己做了大量工作,发送的连续性将扼杀性能:)

成功发送时是否必须使用相同的OVL/buffer对象?我通常做的是为每次发送使用不同的OVL/缓冲区,并立即将其排队。内核将按顺序发送缓冲区,并为每个缓冲区返回一条完成消息。套接字上的多个IOCP tx请求(这就是OVL块的用途)在内核堆栈中将它们链接在一起是没有问题的

让多个IOCP接收针对未完成套接字的请求存在一个问题—两个池线程可能同时获取同一套接字的完成数据包,因此可能导致处理顺序混乱。要“正确”修复该问题,需要在发出的每个rx buffer/OVL对象中增加序列号,并在每个套接字对象中“保存”无序缓冲区,直到处理完所有较早的缓冲区。我怀疑许多IOCP服务器只是通过一次只接收一个rx IOCP请求来回避这个问题(可能以牺牲性能为代价)

如果缓冲区被不断地构造和破坏,那么以这种方式通过大量缓冲区可能会有点费力,所以我通常不会在启动时创建几千个缓冲区,并将它们(好的,指向它们的指针)推到生产者-消费者的“池队列”上,当需要发送或接收时,将其弹出,然后将其重新打开。在发送的情况下,当一个IOCP池线程拾取发送完成消息时,就会发生这种情况。在rx的情况下,当池线程(或池线程已将对象排入队列的其他线程)已对其进行处理且不再需要它时,就会发生这种情况

啊。。您希望向套接字列表发送完全相同的内容,就像聊天服务器类型的东西一样

嗯。那么一个缓冲区和多个OVL块呢?我没有试过,但不明白为什么它不起作用。在单缓冲区对象中,保留一个原子引用计数,记录在“发送到所有客户端”循环中已发送的重叠发送请求数。当您将缓冲区返回到完成数据包中时,将refCount减为零,并在降至0时删除/重新调用缓冲区


我认为这应该行得通,(?)。

我不确定我是否理解其中一些。IOCP通常不在OVL结构中使用hEvent字段。I/O完成通过将完成消息排入“完成端口”(即队列)来发出信号。您似乎正在使用hEvent字段来管理单个发送数据缓冲区和OVL块,以获得一些“不寻常”的额外信号

显然,我不知道你文章的全部内容,但在我看来,你在tx端为自己做了大量工作,发送的连续性将扼杀性能:)

成功发送时是否必须使用相同的OVL/buffer对象?我通常做的是为每次发送使用不同的OVL/缓冲区,并立即将其排队。内核将按顺序发送缓冲区,并为每个缓冲区返回一条完成消息。套接字上的多个IOCP tx请求(这就是OVL块的用途)在内核堆栈中将它们链接在一起是没有问题的

让多个IOCP接收针对未完成套接字的请求存在一个问题—两个池线程可能同时获取同一套接字的完成数据包,因此可能导致处理顺序混乱。要“正确”修复该问题,需要在发出的每个rx buffer/OVL对象中增加序列号,并在每个套接字对象中“保存”无序缓冲区,直到处理完所有较早的缓冲区。我怀疑许多IOCP服务器只是通过一次只接收一个rx IOCP请求来回避这个问题(可能以牺牲性能为代价)

如果缓冲区被不断地构造和破坏,那么以这种方式通过大量缓冲区可能会有点费力,所以我通常不会在启动时创建几千个缓冲区,并将它们(好的,指向它们的指针)推到生产者-消费者的“池队列”上,当需要发送或接收时,将其弹出,然后将其重新打开。在发送的情况下,当一个IOCP池线程拾取发送完成消息时,就会发生这种情况。在rx的情况下,当池线程(或池线程已将对象排入队列的其他线程)已对其进行处理且不再需要它时,就会发生这种情况

啊。。您希望向套接字列表发送完全相同的内容,就像聊天服务器类型一样