加载中...
多线程读写socket导致的数据混乱的原因是什么?
第1节:代码改善:一个“坑爹”的文字类冒险游戏
第2节:在禁止多重继承的情况下,如何设计“直立智慧猩猩”类?
第3节:C++多线程代码中的“乱序”执行现象
第4节:C++中函数指针有什么作用呢?
第5节:为什么我用c++写的游戏那么简陋?
第6节:多线程读写socket导致的数据混乱的原因是什么?
第7节:WebSocket 是什么原理?为什么可以实现持久连接?
第8节:怎样在c++中实现instanceof?
第9节:一个函数多处 return 是好风格吗?
第10节:C++中虚函数相比非虚函数的优势
第11节:为什么 C::C::C::C::foo() 能编译成功?
第12节:如何静态反射C++枚举的名字
第13节:看C++大叔如何拥 java 妹子入怀……
第14节:坨——理解递归实现“汉诺塔”代码的关键
第15节:C++编译器如何实现 const(常量)?
第16节:C++如何为断言加上消息
第17节:初学C++到什么水平,算是合格的初级开发工程师?
第18节:C++编程要避免使用单例模式吗?
第19节:学习C++要学boost库吗?
第20节:C++的继承就是复制吗?
第21节:C++构造函数失败,如何中止创建对象?
第22节:C++学完多线程后,学什么呢?
第23节:string_view 适合用做函数的返回值类型吗?
第24节:为指针取别名,为何影响const属性?
第25节:std::enable_shared_from_this 的存在意义?
第26节:C++模板可变参数如何一次性解包?
第27节:Linux下的c++开发,平时是怎么调试代码的呢?
课文封面

正好《白话 C++》有讲到这个。发送方 发送的报文内容是: “亲爱的,你不胖不瘦真真美啊!”……

问题

知友(知乎网站)问:多线程读写socket导致的数据混乱的原因是什么? 这确实是许多初学网络(socket)编程的同学容易迷糊的地方。

这个问题在生活中可以找到许多极其相似的例子,比如打电话,或者排队。
以下是南老师的回答。

《白话C++》 的例子

正好《白话C++》有讲到这个。发送方 发送的报文内容是: “亲爱的,你不胖不瘦真真美啊!”。
按次序,这句子自然是这么发送过去的:

[发送方]---- !啊美真真瘦不胖不你,的爱亲 ---> [接收方]

如果接收方那边是一位小姑娘(我猜是),并且是一位喜欢并发处理事情的,利索的小姑娘。她启了三个线程同时读取,就可能读成这样:

  1. 第一个读取到:“亲,你不瘦真美”;
  2. 第二个读取到:“爱的不真啊”;
  3. 第三个读取到:“胖!”

(摊手:)小姑娘觉得男友和她说了三句话。

书中下面这张图:

同一socket并发读写造成的数据混乱

解读

并发写造成写入的数据混乱的原因

图中的上半部分:两个线程并发的写。两个线程都在一个字符一个字符地写,一个负责写数字,一个负责写字母,但收到的数据是数字与字母夹杂的字符串。
很好理解:把一个socket连接理解为一条队列,数字理解为一边是男生堆,字母理解为另一边是女生堆;一声令下,两边的人都拼命地往队列里跑过去排队,自然就是男生女生会混在一起。

并发读造成读到的数据混乱的原因

图中下半部分:一份数据、一个连接(或一个socket),多个线程并发的读(图中是三个线程),假设没有按照某种策略读,仅是纯按某个瞬间,数据到达的次序读取,结果就是三个线程各自读了一些数据,谁都没读完整,仿佛是一道密文,被三人分别领取,结果谁也没明白自己读到的是什么。