winsock 2. 同时发送的线程安全。 TCP协议
是否可以有多个线程在同一个套接字上发送?流是否会交错,或者第一个线程上的套接字是否会阻塞(假设是 tcp)?我发现的大多数意见似乎都警告不要这样做,因为明显担心交错,但我也发现了一些相反的评论。交错恐惧是从winsock1 遗留下来的吗?对于winsock2 来说它们是否有充分根据?有没有办法设置一个允许缺乏本地同步的winsock2套接字?
下面两个相反的意见……谁是对的?
comment 1
“Winsock 2 实现应该是完全线程安全的。不同线程上的同时读取/写入应该成功,或者因 WSAEINPROGRESS 而失败,具体取决于创建套接字时重叠标志的设置。无论如何,默认情况下,都会创建重叠套接字;所以你不必担心它。确保你不使用 NT SP6,如果你使用 SP6a,你应该没问题!”
comment 2
"自 Windows 95 引入以来,同一个 DLL 不会被多个进程访问。每个进程都有自己的可写副本DLL 的数据段。“所有进程共享”模型是旧的 Win16 模型,幸运的是,它现在已经死亡并被埋葬了;-)”
期待您的评论! 吉姆
~编辑1~ 澄清我所说的交错的意思。线程 1 发送消息“Hello”,线程 2 发送消息“world!”。收件人收到:“Hwoel lord!”。这假设两条消息都不是在 while 循环中发送的。这可能吗?
is it possible to have multiple threads sending on the same socket? will there be interleaving of the streams or will the socket block on the first thread (assuming tcp)? the majority of opinions i've found seems to warn against doing this for obvious fears of interleaving, but i've also found a few comments that state the opposite. are interleaving fears a carryover from winsock1 and are they well-founded for winsock2? is there a way to setup a winsock2 socket that would allow for lack of local synchronization?
two of the contrary opinions below... who's right?
comment 1
"Winsock 2 implementations should be completely thread safe. Simultaneous reads / writes on different threads should succeed, or fail with WSAEINPROGRESS, depending on the setting of the overlapped flag when the socket is created. Anyway by default, overlapped sockets are created; so you don't have to worry about it. Make sure you don't use NT SP6, if ur on SP6a, you should be ok !"
comment 2
"The same DLL doesn't get accessed by multiple processes as of the introduction of Windows 95. Each process gets its own copy of the writable data segment for the DLL. The "all processes share" model was the old Win16 model, which is luckily quite dead and buried by now ;-)"
looking forward to your comments!
jim
~edit1~
to clarify what i mean by interleaving. thread 1 sends the msg "Hello" thread 2 sends the msg "world!". recipient receives: "Hwoel lorld!". this assumes both messages were NOT sent in a while loop. is this possible?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
无论如何,我真的建议不要这样做。由于各种非常合法的原因,发送函数可能发送的数据少于您告诉它的数据,并且如果另一个线程可能进入并尝试发送某些内容,那么您只是弄乱了数据。
现在,您当然可以从多个线程写入套接字,但您不再能够控制线路上的内容,除非您在应用程序级别进行了适当的锁定。
考虑发送一些数据:
sent
参数将保存编号。实际发送的字节数 - 类似于 send() 函数的返回值。要发送 buf 中的所有数据,您必须循环执行 WSASend,直到所有数据实际发送完毕。例如,如果第一个
WSASend
发送了除最后 4 个字节之外的所有字节,则当您循环返回并尝试发送最后 4 个字节时,另一个线程可能会发送一些内容。通过适当的锁定来确保不会发生这种情况,从多个线程发送应该没有问题 - 无论如何我都不会这样做,只是为了在出现问题时进行调试。
I'd really advice against doing this in any case. The send functions might send less than you tell it to for various very legit reasons, and if another thread might enter and try to also send something, you're just messing up your data.
Now, you can certainly write to a socket from several threads, but you've no longer any control over what gets on the wire unless you've proper locking at the application level.
consider sending some data:
the
sent
parameter will hold the no. of bytes actually sent - similar to the return value of thesend()
function. To send all the data inbuf
you will have to loop doing a WSASend until all all the data actually get sent.If, say, the first
WSASend
sends all but the last 4 bytes, another thread might go and send something while you loop back and try to send the last 4 bytes.With proper locking to ensure that can't happen, it should e no problem sending from several threads - I wouldn't do it anyway just for the pure hell it will be to debug when something does go wrong.
是的 - 不过,根据实现的不同,这可能更多可见或更少可见。首先,我将澄清我的观点:
线程的整体可见性(即所需的管理)和引起的麻烦将直接取决于套接字的实现方式(同步)或异步)。如果您采用同步路线,那么您需要做很多工作来手动管理多个线程上的连接、发送和接收。我强烈建议避免这种实现。在线程模型中正确有效地执行同步方法的努力根本不值得与实现异步方法的类似努力相比。
我实现异步 Tcp 服务器的时间比实现线程同步版本所用的时间要少。异步更容易调试 - 如果您打算使用 Tcp(我最喜欢的选择),那么您真的不用担心丢失消息、丢失数据或其他问题。
我必须研究交错流(来自wiki)以确保我的理解是准确的你在问什么。要进一步了解交错和混合消息,请参阅 wiki 上的以下链接:
具体来说,Tcp 的功能在以下部分:
这意味着交错的消息将被重新排序为发送者发送的各自的消息。预计线程正在或将参与开发性能驱动的 Tcp 客户端/服务器机制 - 无论是通过异步还是同步方法。
为了防止套接字阻塞,您可以将其
Blocking
属性设置为false
。我希望这能为您提供一些有用的信息。哎呀,我什至学到了一点点......
Yes - although, depending on implementation this can be more or less visible. First, I'll clarify where I am coming from:
The overall visibility (i.e. required management) of threading and the headaches incurred will be directly dependent on how the socket is implemented (synchronously or asynchronously). If you go the synchronous route then you have a lot of work to manually manage connecting, sending, and receiving over multiple threads. I highly recommend that this implementation be avoided. The efforts to correctly and efficiently perform the synchronous methods in a threaded model simply are not worth the comparable efforts to implement the asynchronous methods.
I have implemented an asynchronous Tcp server in less time than it took for me to implement the threaded synchronous version. Async is much easier to debug - and if you are intent on Tcp (my favorite choice) then you really have few worries in lost messages, missing data, or whatever.
I had to research interleaved streams (from wiki) to ensure that I was accurate in my understanding of what you are asking. To further understand interleaving and mixed messages, refer to these links on wiki:
Specifically, the power of Tcp is best described in the following section:
What this means is that interleaved messages will be re-ordered into their respective messages as sent by the sender. It is expected that threading is or would be involved in developing a performance-driven Tcp client/server mechanism - whether through async or sync methods.
In order to keep a socket from blocking, you can set it's
Blocking
property tofalse
.I hope this gives you some good information to work with. Heck, I even learned a little bit...