# 線程
線程與進程有很多類似的地方,但是也有部分不一樣。在講進程的時候我們給大家看過一張圖。

<center>圖:1.3-3</center>
從圖:1.3-3中可以看出來線程是在進程內創建的,也就說多個線程共享一個進程內的資源;包括內存、地址空間、文件描述符等等。使用多線程是無序執行的,線程的調度和進程一樣,由操作系統來調度,因此什么時候執行我們并不知道。有一句話可以概括線程:線程就是更輕量的進程。
##### 線程
* 一個進程至少有一個線程
* 同一個進程內的多個線程共享同一份資源
* 文件描述符表
* 信號處理方式
* 當前工作目錄
* 內存地址空間
每個線程有自己的獨立棧,也就是線程內部的變量其他線程拿不到,除非是在進程內的全局變量。
既然有了多進程為什么我們還需要多線程?進程在遇到IO會阻塞,后面的代碼無法執行,這時候CPU處于空跑狀態,為了充分的利用CPU,操作系統會自動把遇到IO阻塞的進程掛起,切換到其他進程。
### 進程上下文

<center>圖:1.3-6</center>
### 線程上下文

<center>圖:1.4-1</center>
操作系統會給每一個進程分配給可用的時間片,就是每個進程每次運行多久,例如:CPU給每個進程分配了10ms的時間,如果一個進程執行到3ms的時候發生了IO阻塞怎么辦呢?在單線程的情況下,會被切換到另一個進程,當前進程會被掛起。而多線程呢,是盡可能的利用完CPU給這個進程分配的時間片。
舉個“栗子”,微信我們大家都在用,微信很顯然就是一個多線程程序,為什么這樣說呢?我們在跟別人視頻的時候同時還可以跟其他人聊天,還可以使用輸入法輸入文字,選擇表情,如果只有一個線程,那么我們在跟別人視頻的時候這個線程就會阻塞,我們看到微信的界面就會卡死。
一個線程遇到阻塞的時候,會在同一個進程內的其他空閑線程切換,這樣的切換只要消耗線程棧開銷,因此很多時候我們都說線程是輕量級的進程。
因此需要把一個進程里面的任務再次分割成任務片,類似CPU分出來的時間片一樣,分成多少份就開多少個線程。
- 第一章:基礎知識
- 課程簡介
- PHP-FPM過渡常駐內存
- 進程
- 實戰:實現Master-Worker
- 線程
- 實戰:CC攻擊器
- 協程
- 實戰:實現waitGroup功能
- 進程、線程、協程的區別
- 第二章:初識Swoft2.0
- Swoft介紹
- Swoft環境安裝
- gcc升級
- 安裝Swoft框架
- 目錄結構介紹
- SwoftCli工具
- Swoft配置
- 第三章:Swoft2.0核心
- 上下文
- 常駐內存沒有上下文隔離
- 實戰:手寫swoole框架上下文管理
- Bean容器
- 實戰:根據容器原理實現容器
- 實戰:通過容器實現依賴注入
- Bean容器定義與使用
- 配置文件定義Bean
- 容器類型
- 面向接口的容器
- 注解
- 實戰:實現注解
- 自定義Swoft注解類
- 事件
- 連接池
- 實戰:Swoole實現連接池
- 第四章:Http服務器
- Http Server生命周期
- Http Server配置
- 控制器
- 路由
- 請求對象Request
- 響應對象Response
- Http異常處理
- 中間件
- 實戰:中間件實現JWT登陸授權
- 第五章:驗證器
- 內置驗證類型
- 驗證器的使用
- 自定義驗證器
- 第六章:數據庫操作
- 連接數據庫
- 實體模型
- 模型事件
- 查詢器
- 事務處理
- 連接池配置
- 讀寫分離
- 多數據庫切換
- Models分層結構
- 實戰:實現用戶CURD API
- 第七章:Redis
- 連接redis和使用
- Redis連接池
- Redis集群配置(單機版)
- Redis集群配置(多服務器)
- Redis連接集群
- Redis實戰:實現延時任務
- 第八章:AOP編程
- AOP概念
- AOP實現原理
- 實戰實現AOP:靜態代理
- 實戰實現AOP:動態代理
- 切面注解介紹
- PointExecution切面
- PointBean切面
- PointAnnotation切面
- 實戰:使用AOP實現日志記錄
- 第九章:任務處理
- 進程使用
- 進程池使用
- 實戰:進程消費隊列
- 實戰:進程實現RabbitMQ延時隊列
- 異步任務
- 協程任務
- 定時任務