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

2023-12-11

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

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

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

...
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 和等待函数是个好主意吗?
任何有关的线索wsasends对于多线程 iocp 服务器中的所有客户端,我们将不胜感激。
thx


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

显然,我没有从你的帖子中了解整个故事,但在我看来,你在 tx 方面为自己做了繁重的工作,并且序列化发送会扼杀性能:)

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

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

如果不断地构建和销毁缓冲区,以这种方式获取大量缓冲区可能会有点费力,所以我通常不会打扰,只是在启动时创建几千个缓冲区并推送它们,(好吧,指向它们的指针) ,到生产者-消费者“池队列”上,当需要 tx 或 rx 时将它们弹出并再次将它们推回。对于 tx,当 IOCP 池线程之一拾取发送完成消息时,就会发生这种情况。在 rx 的情况下,当池线程(或池线程已将对象排队到其中的某个其他线程)已处理该对象并且不再需要它时,就会发生这种情况。

啊..您想将完全相同的内容发送到套接字列表 - 就像聊天服务器类型的东西。

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WSAsend 到多线程 iocp 服务器中所有已连接的套接字 的相关文章

  • 从 C 线程调用 Python 代码

    我对从 C 或 C 线程调用 Python 代码时如何确保线程安全感到非常困惑 The Python 文档 http docs python org c api init html non python created threads似乎是
  • 没有公平性的DelayQueue有问题吗?

    在 Java 7 中 DelayQueue 的实现使用没有公平策略的 ReentrantLock 从长远来看 这是一个问题吗 线程会因此而饿死吗 Thanks 如果您考虑ScheduledThreadPoolExecutor 或任何其他生产
  • java套接字/输出流写入:它们会阻塞吗?

    如果我只写入输出流上的套接字 它会阻塞吗 只有读取才能阻塞 对吗 有人告诉我写入可以阻塞 但我只看到套接字读取方法的超时功能 Socket setSoTimeout 对我来说 写入可能会阻塞是没有意义的 如果我只写入输出流上的套接字 它会阻
  • Python time.sleep - 永不醒来

    我认为这将是那些简单的问题之一 但它让我感到困惑 停止媒体 我是对的 找到了解决方案 查看答案 我正在使用 Python 的单元测试框架来测试多线程应用程序 很好而且很直接 我有 5 个左右的工作线程监视一个公共队列 以及一个为它们制作工作
  • 当应用程序终止时,我可以安全地依赖 Threads 中的 IsBackground 吗?

    我正在 GUI 中运行一些后台线程 目前 我正在实现个人线程取消代码 但线程中有 IsBackground 属性 根据 MSDN 它们会自行取消 我知道它将进入 Thread Abort 这很令人讨厌 但是在这个后台线程中没有任何事情需要我
  • 低级键盘钩子不在 UI 线程上

    我想为键盘挂钩创建一个好的库 我使用 SetWindowsHookEx 方法 我注意到如果我的应用程序的主线程繁忙 则应在任何系统 KeyDown 事件中调用的方法 hookProc 不会执行 我认为钩子应该这样制作 以便另一个线程负责它
  • 如何从 WinRT StreamSocket 读取所有可用数据并清空 inputStream?

    我想在向套接字写入新数据之前读取当前正在等待套接字的所有数据 WinRT中的读取方法都是异步的 所以我不能简单地while直到套接字为空 由于我确实想丢弃套接字上的数据 因此我不想使用读取器 而是直接从套接字读取数据IInputStream
  • 如何在Python中获取套接字的外部IP?

    当我打电话时socket getsockname 在套接字对象上 它返回我的机器的内部 IP 和端口的元组 但是 我想找回我的外部IP 最便宜 最有效的方式是什么 如果没有外部服务器的配合 这是不可能的 因为您和另一台计算机之间可能存在任意
  • 如何从不同的线程访问控件?

    如何从创建控件的线程以外的线程访问控件 避免跨线程错误 这是我的示例代码 private void Form1 Load object sender EventArgs e Thread t new Thread foo t Start p
  • 在特定线程上运行工作

    我想要一个特定的线程 任务队列并在该单独的线程中处理任务 应用程序将根据用户的使用情况创建任务并将其排队到任务队列中 然后单独的线程处理任务 即使队列为空 保持线程活动并使用它来处理排队任务也至关重要 我尝试过几种实现TaskSchedul
  • 重构——套接字中的良好实践——简单的服务器-客户端 Swing 应用程序

    我使用单例和观察者模式编写了一个带有 Swing 接口的简单服务器 客户端程序 每个客户端都连接到服务器并可以发送消息 服务器将其收到的消息转发给其余的客户端 客户端使用 GUI 允许它们随时连接和断开与服务器的连接 该程序运行得很好 因为
  • 为什么一个线程会中断另一个线程[重复]

    这个问题在这里已经有答案了 在Java多线程应用程序中 我们处理InterruptedThreadException 如果另一个线程中断当前线程 则会抛出此异常 现在 当另一个线程知道它将导致异常时 它可能想要中断当前线程的原因是什么 很多
  • Node.js 工作线程中的 I/O 性能

    下面是一个工作线程示例 在本地计算机上同步 I O 大约需要 600 毫秒 const fs require fs const isMainThread Worker parentPort workerData require worker
  • 不支持 STA 线程上多个句柄的 WaitAll

    为什么我会收到此错误消息 不支持 STA 线程上多个句柄的 WaitAll 我应该使用 STAThreadAttribute 属性吗 Update 不适用于 WPF 应用程序 笔记 错误位于 WaitHandle WaitAll doneE
  • Netty Nio java 中的通信

    我想在 Netty nio 中创建一个具有两个客户端和一个服务器的通信系统 更具体地说 首先 我希望当两个客户端与服务器连接时从服务器发送消息 然后能够在两个客户端之间交换数据 我正在使用本示例提供的代码 https github com
  • Java 执行器和长寿命线程

    我继承了一些使用 Executors newFixedThreadPool 4 的代码运行 4 个长寿命线程来完成应用程序的所有工作 这是推荐的吗 我读过Java 并发实践 https rads stackoverflow com amzn
  • Android:如何暂停和恢复可运行线程?

    我正在使用 postDelayed 可运行线程 当我按下按钮时 我需要暂停并恢复该线程 请任何人帮助我 这是我的主题 protected void animation music6 music4 postDelayed new Runnab
  • Python 中 time.sleep 和多线程的问题

    我对 python 中的 time sleep 函数有疑问 我正在运行一个脚本 需要等待另一个程序生成 txt 文件 虽然 这是一台非常旧的机器 所以当我休眠 python 脚本时 我遇到了其他程序不生成文件的问题 除了使用 time sl
  • 单线程程序中可以有竞争条件吗?

    您可以在here https en wikipedia org wiki Race condition Software关于什么是竞争条件的一个很好的解释 我最近看到很多人对竞争条件和线程做出了令人困惑的陈述 我了解到竞争条件只能发生在线程
  • C++11 动态线程池

    最近 我一直在尝试寻找一个用于线程并发任务的库 理想情况下 是一个在线程上调用函数的简单接口 任何时候都有 n 个线程 有些线程比其他线程完成得更快 并且到达的时间不同 首先我尝试了 Rx 它在 C 中非常棒 我还研究了 Blocks 和

随机推荐