mit6824
mapreduceMapReduce (2004)介绍及例子用户需要指定map以及reduce函数,map函数负责建立中间键值的映射关系,reduce将所有的值合并到相同的键上。(如wordcount程序)
12reduce (k2,list(v2)) → list(v2)map (k1,v1) → list(k2,v2)
输入键和值是从与输出键和值不同的域中绘制的。此外,中间键和值与输出键和值来自相同的域。
分布式Grepmap :在匹配到一行时发射一行
reduce:将中间数据复制到输出
url访问频率统计map:输出 <URL, 1>
reduce: 对来自相同url的相加然后发送<URL, TOTAL count>
实现Map调用通过将输入数据自动分割为 M 段 分布在多个机器上。
Map函数执行完之后,会通过分区函数将中间键划分为R个互不重叠的分区。(默认分区函数可以是hash函数,这样可以将相同的键放到同一个分区,即将该类键都分到某一个具体的分区中,由某一个任务执行)
任务粒度当用户提供的map以及reduce操作 ...
tiny_muduo
数组退化数组通常会退化为指针。为了避免退化可以使用模板函数 + 引用参数的形式。
12345template <typename T>void h(T& param);int arr[10];h(arr);
这里 T 只能被推导为 int[10]。(只使用模板函数还是无法避免退化,会将T推导为指针)
extern声明一个变量,告诉编译器它在别的地方有定义。通常将extern声明放到头文件中,将定义放到某个源文件中。这样所有使用该头文件的文件头会获得该声明,但是定义只有一份。
套接字-又名socket套接字层(Socket Layer)位于 应用层和传输层之间。套接字 是一个抽象层,它提供了一个编程接口,让应用程序(应用层)可以调用操作系统提供的功能来使用传输层和网络层的服务。
返回右值分为两种情况,
返回一个临时对象,比如 return object()。
通过std::move 返回一个右值引用,注意返回的右值引用仍然是引用。比如下面的例子
1234567891011121314151617181920212223242526272829303132# ...
muduo
线程安全的对象生命周期管理析构函数&多线程多线程共享对象,对象的线程安全特性可以由对象内的同步原语保护。但是对象的析构没法通过内部的同步原语保护。(猜测要通过外部的同步原语保护)
比如如何保证在执行成员函数期间,对象不会被其他线程析构。
线程安全线程安全的类满足如下三个条件:
多线程可以同时访问,表现正常。
无论这些线程的执行顺序如何交织。
调用端无需同步操作。
C++大部分类,string,vector都不是线程安全的,也可以理解,毕竟需要线程安全的时间也不多,没必要增加额外的开销。
对象构造&线程安全如何保证对象构造的线程安全:在构造期间不要泄露this指针。
可以使用两段式构造。
对象销毁&线程安全很难解决的问题。文章从面对对象程序设计的角度提出了一些问题。
对象的关系包括三种:
composition(组合):如struct A{struct B b;};b的生命周期由A决定,A对象被析构时,b也被析构。
association(关联):在形式上与下面一条很类似,生命周期独立。
aggregation(聚合):如stru ...
xv6
操作系统接口文件描述符每个进程有一个私有的文件描述符表,这是shell可以执行IO重定向以及管道的基础。
每个文件描述符都有一个与文件关联的偏移。
fork后,子进程拥有和父进程一致的文件描述符表,再次执行exec后,也仍然会保留该文件描述符表(除了使用closeonexec选项)。这允许了IO重定向,使得不同的进程可以访问相同的文件描述符。比如cat的实现:cat < input.txt
12345678char *argv[2];argv[0] = "cat";argv[1] = 0;if(fork() == 0) { close(0); open("input.txt", O_RDONLY); exec("cat", argv);}
open默认返回最小未使用的文件描述符:0。
为什么不直接给一个创建新进程的接口,而是分为先fork,再exec,因为这样创建的子进程在fork之后exec之前,还有一段时间,这里可以执行一些任务,比如可以修改文件描述符。(其实exec执行的 ...
Linux高性能服务器编程
1-4章又介绍了TCP/IP协议
TCP/IP协议簇
上面这图很具有误导性,比如ICMP是作为数据封装到IP内,但把他们画到同一层。ARP是作为数据封装到数据链路(比如以太网帧)内,但把他们画到同一层
TCP: 可靠的、面向连接的、基于流的。
UDP: 不可靠、无连接、基于数据报的。
封装&分用:分用指的解析本层书籍,将处理后的数据往上层传。
复位报文段产生复位报文段的三种情况:
访问不存在的端口访问不存在的端口或者该端口处于TIME_WAIT状态,客户端会收到复位报文段。
异常终止连接TCP提供了异常终止一个连接的方式,即向对方发送一个复位报文段。对方收到后,会丢弃所有排队等待发送的数据。
处理半打开连接比如服务端和客户端已经连接上,但是服务端网线被拔了,重新接上后。只有客户端维护着连接,当他往管道写入数据时,会受到一个复位报文段。
TCP交互数据流TCP连接的应用数据分为两类:交互数据和成块数据。
比如通telnet访问服务器,会经过如下过程
每键入一个字符,会将该字符用TCP包发给服务器,服务器回发了确认消息以及数据,客户端立刻回发确认消 ...
图解HTTP
。
实体主体:应该是未压缩时的数据
报文主体:应该是压缩后的数据,
多部分对象集合描述数据类型时,使用multipart格式。
multipart/form-data 在 Web 表单文件上传时使用。
multipart/byteranges 状态码 206(Partial Content,部分内容)响应报文包含了多个范 围的内容时使用。
状态码200表示从客户端发来的请求在服务器端被正常处理了。
204该状态码代表服务器接收的请求已成功处理,但在返回的响应报文中 不含实体的主体部分。
206该状态码表示客户端进行了范围请求,而服务器成功执行了这部分的 GET 请求。响应报文中包含由 Content-Range 指定范围的实体内容。
3XX 重定向3XX 响应结果表明浏览器需要执行某些特殊的处理以正确处理请 求。
301 Moved Permanently永久性重定向。该状态码表示请求的资源已被分配了新的 URI,以后 应使用资源现在所指的 URI。
302 Found和 301 Moved Permanently 状态码相似,但 302 ...
自顶向下方法
计算机网络与因特网应用层安全套接字层(SSL),位于应用层,可以对数据加密。
网络应用:Web应用,电子邮件应用
应用层协议:HTTP, SMTP
本章讨论物种应用:Web、文件传输、电子邮件、目录服务、流式视频与P2P。
DNS
递归查询
将任务交给一个DNS服务器就不管了,最终会得到查询的结果。
迭代查询
将任务交给一个DNS服务器后,DNS服务器会返回新的DNS服务器,这些需要本机自己去查。
查询通常遵 循图2-18 中的模式: 从请求主机到本地 DNS 服务器的查询是递归的、其余的查询 根DNS服务器是迭代的。1,8是递归的,其他是迭代的
运输层UDP
长度 ,首部+数据
校验和,对所有16比特数据进行求和、回卷、反码计算。
可靠传输基于完全可行信道传输rdt1.0不用担心差错随便发
基于有比特差错信道的可靠数据传输(信道上发送的包某些位可能改变,但信道不会有其他问题,比如丢包等)rdt2.0接收方通过ACK和NAK来确认,有NAK就会重传。
本协议基本可行,但有一个缺陷:数据发送方收到了出错的ACK和NAK包怎么办,数据发送方当然可以重发前一个包,但发 ...
程序员的自我修养-第十一章
运行库
入口函数和程序初始化程序从main开始吗
程序员的自我修养-第十章
内存
程序的内存布局
栈与调用惯例什么是栈
栈会保存一个函数调用所需要的维护信息(又名堆栈帧或活动记录),它包含:
函数的返回地址和参数
临时变量
保存的上下文(应该是自己的上下文,而不是调用自己的函数的上下文吧)
活动记录由ebp和esp这两个寄存器来划分范围。
感觉上图ebp的位置有一点问题,应该指向old ebp才对,看下面的i386函数体开头
之所以活动记录是这样的,是因为函数调用本身就是这么设计的:
i386下的函数调用:
把所有或一部分参数压入栈中,如果有其他参数没有入栈,那么使用某些特定的寄存器传递。
把当前指令的下一条指令的地址压入栈中。
跳转到函数体执行。
i386下的函数体开头
push ebp:把 ebp 压入栈中(称为 old ebp)。
mov ebp, esp:ebp = esp(这时 ebp 指向栈顶,而此时栈顶就是 old ebp)。
【可选】sub esp, XXX:在栈上分配 XXX 字节的临时空间。
【可选】push XXX:如有必要,保存名为 XXX 寄存器(可重复多个)。
函数返回的标准结尾
【可 ...