【问题标题】:.NET C# Socket Concurrency issues.NET C# 套接字并发问题
【发布时间】:2009-08-26 19:53:55
【问题描述】:

System.Net.Sockets.Socket 的一个实例

可以被 2 个线程共享,所以一个使用 send() 方法,另一个使用 receive() 方法?

安全吗?

嗯,我需要它不仅是线程安全的,而且发送/接收方法是非同步的,以便让每个线程同时调用它们。

我还有其他方法吗?

感谢您的帮助,我在 java 方面有经验,但很难尝试制作这个。

【问题讨论】:

    标签: c# .net multithreading sockets thread-safety


    【解决方案1】:

    应该是安全的,是的。 Socket 类由MSDN to be fully thread-safe 引用。

    我不知道这是否是个好主意。使用两个线程可能会使您自己变得困难。您可能希望查看 BeginSendBeginReceive 的异步版本,在这种情况下您不需要多个线程。

    【讨论】:

    • 首先,我不仅关心线程安全,还关心读/写的并发使用。嗯,好的,让我再问一些问题,请回答我。在幕后,这些异步方法的使用管理另一个线程来实现 asincronicity rigth 吗?如果是这样,每次我调用 begin...,它会创建一个新线程吗?
    • 据我所知,创建了一个新线程,但它不会是每个调用的新线程。我做了一个小测试来确认,看起来确实是这样。
    • 我相信异步方法使用线程池线程,而不是创建特定的新线程
    • @Matt:确实如此。它可能会或可能不会启动新线程,具体取决于线程池中空闲线程的可用性。区别通常是不相关的,所以我最初将其省略了。这里有一些信息:msdn.microsoft.com/en-us/library/ms973903.aspx
    【解决方案2】:

    有点离题,但仅当您的客户端有限时,使用去同步方法才有用。我发现异步套接字的响应速度较慢。异步套接字在处理许多客户端时要好得多。

    所以: 同步速度更快。 async 更具可扩展性

    【讨论】:

      【解决方案3】:

      是的,同时从两个不同的线程访问发送和接收是完全安全的。

      如果您希望您的应用程序扩展到 100 个活动套接字,那么您需要使用 BeginReceiveve/BeginSend 方法,而不是手动创建线程。这将在幕后发挥作用,这样您就不会产生 100 个线程来处理套接字。它究竟做了什么取决于平台。在 Windows 上,您将使用“高性能”io 完成端口。在 linux (mono) 下,我相信你会使用 epoll。无论哪种方式,您最终都会使用比活动套接字少得多的线程,这总是一件好事:)

      【讨论】:

      • 为什么说使用专用线程进行接收/发送会比使用异步方法带来更大的延迟或可扩展性问题?
      • 假设您有 500 个打开的套接字,而您只是从它们那里接收数据。您需要启动 500 个线程,每个线程都阻塞在 Socket.Receive() 上。现在,假设您使用了该方法的异步 BeginReceive 版本。 .NET 运行时会将套接字交给操作系统并说“当它们有数据时告诉我”。当他们有数据时,运行时将从线程池中获取一个线程并调用 AsyncCallback 以便您可以处理您的数据。这比上下文切换 500 个线程的性能要很多
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-12-19
      • 1970-01-01
      • 1970-01-01
      • 2010-12-15
      • 1970-01-01
      • 2011-07-09
      • 1970-01-01
      相关资源
      最近更新 更多