From 95cb69fadd55bfe10124357efdf4f70536537238 Mon Sep 17 00:00:00 2001 From: CyC2018 <1029579233@qq.com> Date: Sat, 14 Apr 2018 15:10:47 +0800 Subject: [PATCH] auto commit --- notes/HTTP.md | 10 ++-- notes/Linux.md | 51 ++++++++++++++---- notes/正则表达式.md | 26 ++++----- pics/600e9c75-5033-4dad-ae2b-930957db638e.png | Bin 0 -> 12288 bytes 4 files changed, 63 insertions(+), 24 deletions(-) create mode 100644 pics/600e9c75-5033-4dad-ae2b-930957db638e.png diff --git a/notes/HTTP.md b/notes/HTTP.md index 7238542e..97f361c9 100644 --- a/notes/HTTP.md +++ b/notes/HTTP.md @@ -507,7 +507,7 @@ HTTP/1.1 使用虚拟主机技术,使得一台服务器拥有多个域名, ### 3. 隧道 -使用 SSL 等加密手段,为客户端和服务器之间建立一条安全的通信线路。隧道本身不去解析 HTTP 请求。 +使用 SSL 等加密手段,为客户端和服务器之间建立一条安全的通信线路。 # 六、HTTPs @@ -810,9 +810,11 @@ DELETE /idX/delete HTTP/1.1 -> Returns 404 ## HTTP/1.1 与 HTTP/2.0 的区别 +> [HTTP/2 简介](https://developers.google.com/web/fundamentals/performance/http2/?hl=zh-cn) + ### 1. 多路复用 -HTTP/2.0 使用多路复用技术,使用同一个 TCP 连接来处理多个请求。 +HTTP/2.0 使用多路复用技术,同一个 TCP 连接可以处理多个请求。 ### 2. 首部压缩 @@ -820,7 +822,7 @@ HTTP/1.1 的首部带有大量信息,而且每次都要重复发送。HTTP/2.0 ### 3. 服务端推送 -在客户端请求一个资源时,会把相关的资源一起发送给客户端,客户端就不需要再次发起请求了。例如客户端请求 index.html 页面,服务端就把 index.js 一起发给客户端。 +HTTP/2.0 在客户端请求一个资源时,会把相关的资源一起发送给客户端,客户端就不需要再次发起请求了。例如客户端请求 index.html 页面,服务端就把 index.js 一起发给客户端。 ### 4. 二进制格式 @@ -848,3 +850,5 @@ HTTP/1.1 的解析是基于文本的,而 HTTP/2.0 采用二进制格式。 - [XMLHttpRequest](https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest) - [XMLHttpRequest (XHR) Uses Multiple Packets for HTTP POST?](https://blog.josephscott.org/2009/08/27/xmlhttprequest-xhr-uses-multiple-packets-for-http-post/) - [Symmetric vs. Asymmetric Encryption – What are differences?](https://www.ssl2buy.com/wiki/symmetric-vs-asymmetric-encryption-what-are-differences) +- [Web 性能优化与 HTTP/2](https://www.kancloud.cn/digest/web-performance-http2) +- [HTTP/2 简介](https://developers.google.com/web/fundamentals/performance/http2/?hl=zh-cn) diff --git a/notes/Linux.md b/notes/Linux.md index dbeddf16..6c38a0fb 100644 --- a/notes/Linux.md +++ b/notes/Linux.md @@ -50,8 +50,11 @@ * [九、进程管理](#九进程管理) * [查看进程](#查看进程) * [进程状态](#进程状态) - * [SIGCHILD](#sigchild) - * [孤儿进程和僵死进程](#孤儿进程和僵死进程) + * [SIGCHLD](#sigchld) + * [wait()](#wait) + * [waitpid()](#waitpid) + * [孤儿进程](#孤儿进程) + * [僵死进程](#僵死进程) * [十、I/O 复用](#十io-复用) * [概念理解](#概念理解) * [I/O 模型](#io-模型) @@ -1061,7 +1064,6 @@ daemon 2

- | 状态 | 说明 | | :---: | --- | | R | running or runnable (on run queue) | @@ -1070,26 +1072,56 @@ daemon 2 | Z | defunct/zombie, terminated but not reaped by its parent | | T | stopped, either by a job control signal or because it is being traced| -## SIGCHILD +## SIGCHLD 当一个子进程改变了它的状态时:停止运行,继续运行或者退出,有两件事会发生在父进程中: - 得到 SIGCHLD 信号; -- 阻塞的 waitpid(2)(或者 wait)调用会返回。 +- waitpid() 或者 wait() 调用会返回。

-## 孤儿进程和僵死进程 +其中子进程发送的 SIGCHLD 信号包含了子进程的信息,包含了进程 ID、进程状态、进程使用 CPU 的时间等。 -### 1. 孤儿进程 +在子进程退出时,它的进程描述符不会立即释放,这是为了让父进程得到子进程信息。父进程通过 wait() 和 waitpid() 来获得一个已经退出的子进程的信息。 + +## wait() + +```c +pid_t wait(int *status) +``` + +父进程调用 wait() 会一直阻塞,直到收到一个子进程退出的 SIGCHLD 信号,之后 wait() 函数会销毁子进程并返回。 + +如果成功,返回被收集的子进程的进程 ID;如果调用进程没有子进程,调用就会失败,此时返回 - 1,同时 errno 被置为 ECHILD。 + +参数 status 用来保存被收集进程退出时的一些状态,如果我们对这个子进程是如何死掉的毫不在意,只想把这个僵尸进程消灭掉,我们就可以设定这个参数为 NULL: + +```c +pid = wait(NULL); +``` + +## waitpid() + +```c +pid_t waitpid(pid_t pid,int *status,int options) +``` + +作用和 wait() 完全相同,但是多了两个可由用户控制的参数 pid 和 options。 + +pid 参数指示一个子进程的 ID,表示只关心这个子进程的退出 SIGCHLD 信号。如果 pid=-1 时,那么贺 wait() 作用相同,都是关心所有子进程退出的 SIGCHLD 信号。 + +options 参数主要有 WNOHANG 和 WUNTRACED 两个选项,WNOHANG 可以使 waitpid() 调用变成非阻塞的,也就是说它会立即返回,父进程可以继续执行其它任务。 + +## 孤儿进程 一个父进程退出,而它的一个或多个子进程还在运行,那么这些子进程将成为孤儿进程。孤儿进程将被 init 进程(进程号为 1)所收养,并由 init 进程对它们完成状态收集工作。 由于孤儿进程会被 init 进程收养,所以孤儿进程不会对系统造成危害。 -### 2. 僵死进程 +## 僵死进程 -一个子进程的进程描述符在子进程退出时不会释放,只有当父进程通过 wait 或 waitpid 获取了子进程信息后才会释放。如果子进程退出,而父进程并没有调用 wait 或 waitpid,那么子进程的进程描述符仍然保存在系统中,这种进程称之为僵死进程。 +一个子进程的进程描述符在子进程退出时不会释放,只有当父进程通过 wait() 或 waitpid() 获取了子进程信息后才会释放。如果子进程退出,而父进程并没有调用 wait() 或 waitpid(),那么子进程的进程描述符仍然保存在系统中,这种进程称之为僵死进程。 僵死进程通过 ps 命令显示出来的状态为 Z。 @@ -1397,3 +1429,4 @@ poll 没有最大描述符数量的限制,如果平台支持应该采用 poll - [Linux 之守护进程、僵死进程与孤儿进程](http://liubigbin.github.io/2016/03/11/Linux-%E4%B9%8B%E5%AE%88%E6%8A%A4%E8%BF%9B%E7%A8%8B%E3%80%81%E5%83%B5%E6%AD%BB%E8%BF%9B%E7%A8%8B%E4%B8%8E%E5%AD%A4%E5%84%BF%E8%BF%9B%E7%A8%8B/) - [Linux process states](https://idea.popcount.org/2012-12-11-linux-process-states/) - [GUID Partition Table](https://en.wikipedia.org/wiki/GUID_Partition_Table) +- [详解 wait 和 waitpid 函数](https://blog.csdn.net/kevinhg/article/details/7001719) diff --git a/notes/正则表达式.md b/notes/正则表达式.md index bd38a392..1252be08 100644 --- a/notes/正则表达式.md +++ b/notes/正则表达式.md @@ -19,7 +19,7 @@ 正则表达式内置于其它语言或者软件产品中,它本身不是一种语言或者软件。 -[正则表达式在线工具](http://tool.oschina.net/regex/) +[正则表达式在线工具](https://regexr.com/) # 二、匹配单个字符 @@ -164,7 +164,7 @@ a.+c ^ 元字符在字符集合中用作求非,在字符集合外用作匹配字符串的开头。 -使用 (?m) 来打开分行匹配模式,在该模式下,换行被当做字符串的边界。 +分行匹配模式(multiline)下,换行被当做字符串的边界。 **应用** @@ -173,10 +173,10 @@ a.+c **正则表达式** ``` -(?m)^\s*//.*$ +^\s*\/\/.*$ ``` -如果没用 (?m),则只会匹配 // 注释 1 以及之后的所有内容。用了分行匹配模式之后,换行符被当成是字符串分隔符,因此能正确匹配出两个注释内容。 +

**匹配结果** @@ -197,7 +197,7 @@ a.+c **正则表达式** ``` -(ab) {2,} +(ab){2,} ``` **匹配结果** @@ -222,21 +222,23 @@ a.+c 匹配 IP 地址。IP 地址中每部分都是 0-255 的数字,用正则表达式匹配时以下情况是合法的: -1. 一位或者两位的数字 -2. 1 开头的三位数 -3. 2 开头,第 2 位是 0-4 的三位数 -4. 25 开头,第 3 位是 0-5 的三位数 +1. 一位数字 +2. 不以 0 开头的两位数字 +3. 1 开头的三位数 +4. 2 开头,第 2 位是 0-4 的三位数 +5. 25 开头,第 3 位是 0-5 的三位数 **正则表达式** ``` -(((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5]))\.) {3}(((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5]))) +(((\d)|([1-9]\d)|(1\d{2})|(2[0-4]\d)|(25[0-5]))\.){3}(((\d)|([1-9]\d)|(1\d{2})|(2[0-4]\d)|(25[0-5]))) ``` **匹配结果** 1. **192.168.0.1** -2. 555.555.555.555 +2. 00.00.00.00 +3. 555.555.555.555 # 八、回溯引用 @@ -251,7 +253,7 @@ a.+c \1 将回溯引用子表达式 (h[1-6]) 匹配的内容,也就是说必须和子表达式匹配的内容一致。 ``` -<(h[1-6])>\w*? +<(h[1-6])>\w*?<\/\1> ``` **匹配结果** diff --git a/pics/600e9c75-5033-4dad-ae2b-930957db638e.png b/pics/600e9c75-5033-4dad-ae2b-930957db638e.png new file mode 100644 index 0000000000000000000000000000000000000000..bf0834d5386fbcb585abb4c22bc4490c460abef6 GIT binary patch literal 12288 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 literal 0 HcmV?d00001