现象描述:
1、使用SocketAsyncEventArgs建立异步Socket服务器,接收从客户端发来的数据
2、与网络无关的数据处理线程的某些操作,貌似对Socket接收线程造成影响,导致网络接收流量大幅下降,从而导致客户端发送队列阻塞
3、屏蔽该数据处理线程的某些操作,网络接收流量可达到99%
4、接收线程并没有做过多费时工作,只是将数据压入某队列,然后继续调用接收下一包问题
异步Socket的数据接收线程是从系统线程池中取得,是否存在与其他数据处理线程的资源争用(比如线程的开启关闭调度等),导致内核级的开销,使Socket接收线程受到影响
1、使用SocketAsyncEventArgs建立异步Socket服务器,接收从客户端发来的数据
2、与网络无关的数据处理线程的某些操作,貌似对Socket接收线程造成影响,导致网络接收流量大幅下降,从而导致客户端发送队列阻塞
3、屏蔽该数据处理线程的某些操作,网络接收流量可达到99%
4、接收线程并没有做过多费时工作,只是将数据压入某队列,然后继续调用接收下一包问题
异步Socket的数据接收线程是从系统线程池中取得,是否存在与其他数据处理线程的资源争用(比如线程的开启关闭调度等),导致内核级的开销,使Socket接收线程受到影响
Socket要做到准确接收,不分包是不可能的,至少要在数据包的头部定义长度。
接收到数据后的回调操作是在线程池里,你的处理队列的线程我不知道是通过什么方式,是一直有一个线程在轮循队列,还是往队列里添加新数据时判断队列是否为空,为空则启动新的线程来处理。
如果担心线程调度会影响性能,使用BeginInvoke也是在调用系统线程池的线程进行处理。
不过我觉得更好的方式是不主动使用新线程来处理队列。回调后的操作本身就在线程池,那么接收到数据后,直接进行下一次接收,然后在本线程判断队列是否为空,为空则处理,不为空则仅仅添加(队列每处理完一个包后检测队列是否为空,不为空则继续处理)。这样并不影响处理之前进行的下一次接收回调时使用线程池里面的其他线程。
接收的回调函数向一个队列里Push操作(lock队列),紧接着进行下一次接收
另外一个处理线程轮询队列Pop操作(lock队列),并解析处理数据(对于解出普通控制消息包直接回应,对于解出的数据包仍另外线程处理)
我所指的貌似影响接收的是另外一个数据包解析线程原因是如果在接收线程里及解析处理数据会影响下一次接收
另外数据包解析耗费一定时间,仍另外线程处理
如果先添加到队列,再执行下一次ReceiveAsync,就是你说的“如果在接收线程里及解析处理数据会影响下一次接收”。
我怀疑是不是因为,我所启动的线程与线程池中异步Socket回调线程发生了资源争用什么的,导致影响了接收线程从网卡取数据,并返回给上层
我前面说的其实是向队列添加数据包这个操作都要放到下一个receiveasync调用之后,而不是之前。当然这样同样也避免不了争用,毕竟多线程不能实质上解决资源问题。
另我的机器是x3650服务器,8核cpu,内存12G,程序正常运行时有50多个线程
我奇怪的是 存在问题的代码是数据包处理一个方法中的一条语句list<T>.AddRange(List<xxx> A),A为解析出的数据集合,如果参数A是我自己在方法内部new出来的,就没问题,如果是方法传入的就有问题(影响网络接收),很是诡异。