可能有人解释的区别是什么之间epoll
,poll
和线程池?
epoll
和poll
有特定的Linux ...是否有适用于Windows的等量替代?我的问题是与我的同事讨论C++与C#的争论.
我们已经实现了一个接收大量UDP流的服务器.此服务器使用异步套接字和使用完成端口的重叠I/O在C++中开发.我们使用5个完成端口和5个线程.该服务器可以轻松处理千兆网络上的500 Mbps吞吐量,而不会丢失数据包/错误(我们没有将测试推送到500 Mbps以上).
我们尝试在C#中重新实现相同类型的服务器,但我们无法达到相同的传入吞吐量.我们使用异步接收使用ReceiveAsync
方法和池SocketAsyncEventArgs
来避免为每个接收调用创建新对象的开销.每个SAEventArgs
都有一个缓冲区设置,所以我们不需要为每次接收分配内存.该池非常非常大,因此我们可以排队超过100个接收请求.此服务器无法处理超过240 Mbps的传入吞吐量.超过该限制,我们在UDP流中丢失了一些数据包.
我的问题是:我应该期望使用C++套接字和C#套接字获得相同的性能吗?我的观点是,如果在.NET中正确管理内存,它应该是相同的性能.
附带问题:有人会知道一篇很好的文章/参考资料,解释.NET套接字如何使用I/O完成端口吗?
我想知道哪种方法更快,为什么?
在编写Win32服务器的过程中,我已经阅读了很多有关完成端口和重叠I/O的内容,但是我没有读过任何内容来暗示哪一组API在服务器中产生最佳结果.
我应该使用完成例程,还是应该使用WaitForMultipleObjects API?为什么?
基于众多书籍和博客,包括这里的优秀书籍,很明显当一个人写一个暴露助手异步方法的DLL库,即包装器方法时,通常认为内部完成实际异步方法的I/O任务的最佳实践在这样的线程池线程上(为了简洁起见,下面显示了伪代码,我将其HttpClient
用作示例)
public Async Task<HttpResponseMessage> MyMethodAsync(..)
{
...
var httpClient = new HttpClient(..);
var response = await httpClient.PostAsJsonAsync(..).ConfigureAwait(false);
...
return response;
}
Run Code Online (Sandbox Code Playgroud)
这里的关键是使用ConfigureAwait(false)
IO任务完成发生在线程池线程而不是原始线程上下文,从而可能防止死锁.
我的问题是从来电者的角度来看.我对调用者和上面的方法调用之间存在多层方法调用的情况特别感兴趣,如下例所示.
CallerA -> Method1Async -> Method2Async -> finally the above MyMethodAsync
Run Code Online (Sandbox Code Playgroud)
是仅仅ConfigureAwait(false)
使用最终方法还是应该确保Method1Async
并在Method2Async
内部调用其异步方法ConfigureAwait(false)
?将它包含在所有这些中间方法中似乎很愚蠢,特别是如果Method1Async
并且Method2Async
只是最终调用的重载MyMethodAsync
.有任何想法,请指教!
更新了示例 所以如果我有一个带有以下私有异步方法的库,
private async Task<string> MyPrivateMethodAsync(MyClass myClass)
{
...
return await SomeObject.ReadAsStringAsync().ConfigureAwait(false);
}
Run Code Online (Sandbox Code Playgroud)
我应该确保以下公共重载方法还包括ConfigureAwait(false),如下所示?
public async Task<string> MyMethodAsync(string from)
{
return await MyPrivateMethodAsync(new (MyClass() { From …
Run Code Online (Sandbox Code Playgroud) .net c# task-parallel-library async-await io-completion-ports
我正在开发一个应用程序,它需要一种类型的消息才能访问数据库,而另一种类型的消息则需要一些外部的xml api.
我必须处理A LOT ...其中一个重大挑战是让HttpWebRequest类表现良好.我最初开始只使用标准的同步方法和线程整个事情.这不好.
因此,经过一些阅读后,我看到推荐的方法是使用Begin/End方法将工作委托给IO完成端口,从而释放线程池并产生更好的性能.这似乎不是这样的......性能稍微好一些,但我当然看不到与threadpool相比使用的IO完成端口.
我有一个旋转的线程,并向我发送线程池中可用的工作线程+完成端口.完成端口总是非常低(我看到最多使用9个)并且我总是使用大约120个工作线程(有时更多).我在以下所有方法中使用开始/结束模式httpwebrequest
:
Begin/EndGetRequestStream
Begin/EndWrite (Stream)
Begin/EndGetResponse
Begin/EndRead (Stream)
Run Code Online (Sandbox Code Playgroud)
我做得对吗?我错过了什么吗?我可以同时使用(有时)多达2048个http连接(来自netstat输出) - 为什么完成端口号会这么低?
如果有人能就如何处理这个管理工作线程,完成端口提供一些认真的建议,httpwebrequest
那将非常感谢!
编辑:.NET是一个合理的工具吗?我可以使用.NET和System.Net堆栈获得大量的http连接吗?有人建议使用像WinHttp(或其他一些C++库)这样的东西,并从.NET中调用它,但这不是我特别想做的事情!
c# multithreading httpwebrequest threadpool io-completion-ports
我正在使用boost :: asio进行一个项目,其中同一台机器上的两个进程使用TCP/IP进行通信.一个生成要由另一个读取的数据,但我遇到的问题是间歇性地没有数据通过连接发送.基于异步tcp echo服务器示例,我将其简化为下面的一个非常简单的示例.
这些流程(下面的源代码)很好地开始,从发送方到接收方以快速的速度提供数据.然后突然间,根本没有数据被传递大约五秒钟.然后再次传送数据,直到下一个无法解释的暂停.在这五秒钟内,进程占用0%的CPU,并且没有其他进程似乎特别做任何事情.暂停总是相同的长度 - 五秒钟.
我试图弄清楚如何摆脱这些摊位以及导致它们的原因.
请注意在运行过程中如何有三次CPU使用率下降 - "运行"是服务器进程和客户端进程的单次调用.在这些逢低期间,没有提供数据.运行之间的下降次数和时间有所不同 - 有时甚至没有下降,有时很多.
我可以通过改变读缓冲区的大小来影响这些停顿的"概率" - 例如,如果我使读缓冲区成为发送块大小的倍数,则看起来这个问题几乎消失了,但并非完全消失.
我用Visual Studio 2005编译了下面的代码,使用了Boost 1.43和Boost 1.45.我已经在Windows Vista 64位(四核)和Windows 7 64位(四核和双核)上进行了测试.
服务器接受连接,然后只读取和丢弃数据.每当执行读取时,都会发出新的读取.
客户端连接到服务器,然后将一堆数据包放入发送队列.在此之后,它一次写入一个数据包.只要写入完成,就会写入队列中的下一个数据包.一个单独的线程监视队列大小,并每秒将其打印到stdout.在io停顿期间,队列大小保持完全相同.
我曾尝试使用scatter io(在一次系统调用中写入多个数据包),但结果是一样的.如果我在Boost中禁用IO完成端口BOOST_ASIO_DISABLE_IOCP
,问题似乎就会消失,但代价是吞吐量明显降低.
// Example is adapted from async_tcp_echo_server.cpp which is
// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Start program with -s to start as the server
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif
#include …
Run Code Online (Sandbox Code Playgroud) 我拉着我的头发试图找出一个串口何时完成关闭所以我可以重新打开它.事实证明,CloseHandle()
在端口实际解锁之前返回.
我使用打开一个串行端口CreateFile(FILE_FLAG_OVERLAPPED)
,使用它与一个完成端口关联CreateIoCompletionPort()
,读/写使用它ReadFile()
,WriteFile()
并用关闭它CloseHandle()
.
我注意到如果我快速关闭并重新打开一个串口,我就会ERROR_ACCESS_DENIED
回来CreateFile()
.尽管我正在等待CloseHandle()
返回,然后等待与该句柄相关的所有未完成的读/写操作从完成端口返回,但这种情况正在发生.肯定有更好的方法:)
如何同步关闭串口?请不要重试循环,睡眠()或其他一些廉价的黑客攻击.
编辑:也许这与我使用完成端口和FILE_FLAG_OVERLAPPED有关.当读/写操作完成时,我得到一个回调.端口关闭是否有某种回调?
我正在为我的分布式系统编写一个消息层.我正在使用IOCP,即Socket.XXXAsync方法.
这里有一些非常接近我正在做的事情(事实上,我的接收功能是基于他的):http: //vadmyst.blogspot.com/2008/05/sample-code-for-tcp-server-using.html
我现在发现的是,在程序开始时(两个测试服务器相互通信)我每次都会得到一些SAEA对象,其中.Buffer完全用零填充,但.BytesTransferred的大小是缓冲区(在我的情况下为1024).
这是什么意思?我需要检查一个特殊情况吗?我的系统将此解释为一条不完整的消息并继续前进,但我想知道我是否真的丢失了一些数据.我的印象是,如果没有收到任何内容,你就不会收到回调.在任何情况下,我都可以在WireShark中看到没有任何零长度数据包进入.
我用Google搜索时发现了以下内容,但我不确定我的问题是否相同:http: //social.msdn.microsoft.com/Forums/en-US/ncl/thread/40fe397c-b1da-428e -a355-ee5a6b0b4d2c
http://go4answers.webhost4life.com/Example/socketasynceventargs-buffer-not-ready-121918.aspx
我目前正在研究一种基于使用 IO 完成端口的命名管道的 IPC 机制。
不幸的是,我在使用 msdn 文档时遇到了一些麻烦,因为我不清楚在哪种情况下调用 ReadFile/WriteFile 会产生完成数据包。
当 ERROR_IO_PENDING 返回 FALSE 时的情况很清楚,但是当返回 ERROR_MORE_DATA 时明显可能的情况又如何呢?这种情况下会有完成包吗?另外,如果返回其他错误怎么办?在哪些情况下我必须直接处理结果并释放资源,而不是在完成处理程序中?
另一种情况是 ReadFile/WriteFile 甚至成功,这显然也是可能的。值得庆幸的是,MSDN对此非常清楚:
此外,WriteFile 函数有时会返回 TRUE,且 GetLastError 值为 ERROR_SUCCESS,即使它使用的是异步句柄(也可能因 ERROR_IO_PENDING 而返回 FALSE)。...在此示例中,建议允许完成端口例程单独负责此类资源的所有释放操作。
这个建议在所有情况下都是正确的吗?分配给完成端口的句柄的 ReadFile/WriteFile 操作的结果实际上可以(并且应该)完全被忽略,因为数据包无论如何都会发送到端口?
windows winapi named-pipes overlapped-io io-completion-ports
据我了解,Linux没有IO完成端口。这可能就是为什么在 Scala (JVM) 中开发人员应该显式通知的
原因API 有关阻塞操作的原因。
然而,任务并行库似乎并没有因为这些细节而困扰开发人员。一切都开箱即用。
但是在 Linux 上使用 Mono/NetCore 时如何避免线程匮乏呢?
linux asynchronous task-parallel-library io-completion-ports .net-core
c# ×4
winapi ×3
windows ×3
.net ×2
asynchronous ×2
sockets ×2
.net-core ×1
async-await ×1
asyncsocket ×1
boost-asio ×1
c++ ×1
epoll ×1
io ×1
iocp ×1
linux ×1
named-pipes ×1
performance ×1
serial-port ×1
threadpool ×1