我在公共(public)套接字上发送了多个greenlet。是否可以保证通过socket.sendall发送的每个程序包都被很好地分隔开,还是必须在每次调用sendall之前获取一个锁。
因此,我想防止出现以下情况:

  • g1发送ABCD
  • g2发送1234
  • 接收到的数据混合在一起,例如AB1234CD
  • 预期为ABCD12341234ABCD

  • 更新
    看完sourcecode之后,我认为这种情况不会发生。但是我必须使用锁,因为g1或g2可能会在sendall上崩溃。有人可以确认吗?

    最佳答案

    我使用高延迟/低bandwitch界面进行了一些测试,并得到了预期的错误。

  • 慢速接口(interface)的仿真:https://superuser.com/a/147434
  • 测试脚本:https://gist.github.com/4249827/6779dfbebc255e81252e9b29c94add98c5771669

  • 导致(如预期的那样)导致以下错误:
    AssertionError: This event is already used by another greenlet: (<Greenlet
    at 0x7f3e758722d0: <bound method socket.sendall of <socket at 0x7f3e7587719
    0 fileno=8 sock=127.0.0.1:1234 peer=127.0.0.1:51042>>('11111111111111111111
    11111111111111111111111111111)>, timeout('timed out',))
    

    这是带有gevent.coros.RLock的固定测试脚本,不会产生此错误:https://gist.github.com/4249827/7f02f805331eda4091ae0b39dfea4b102cdba2fa

    09-30 21:56