## 進程是什么?
> Linux進程是一個其中運行著一個或多個線程的地址空間和這些線程所需要的系統資源,Linux系統會在進程之間共享程序代碼和系統函數庫。
Linux 系統中進程存在父子關系,父進程擁有多個子進程,子進程只能有一個父進程。pid為0的進程為調度進程,也是根進程。系統中所有的進程構成了一個以調度進程為根的進程樹。
## 進程的狀態
* D(不可中斷休眠狀態)——進程正在休眠并且不能恢復,直到一個事件發生為止。
* R(運行狀態)——進程正在運行。
* S(休眠狀態)——進程沒有在運行,而在等待一個事件或是信號。
* T(停止狀態)——進程被信號停止,比如,信號 SIGINT 或 SIGSTOP。
* Z(僵死狀態)——標記為 的進程是僵死的進程,它們之所以殘留是因為它們的父進程適當地銷毀它們。如果父進程退出,這些進程將被 init 進程銷毀。
## 父進程與子進程
當父進程通過fork創建子進程,會復制父進程中的數據區、BSS區、堆棧、命令行參數以及環境變量表到子進程中,只有代碼區是共享的。
為了創建子進程能更加的輕量,fork創建子進程時,不會進行復制的動作,子進程和父進程共享內存區,只有當子進程對數據進行寫操作時,才會從父進程的內存區中復制到子進程的內存區,并進行寫操作,復制以內存頁為單位進行復制。這樣就達到了延遲復制加載,減少了系統開銷。
## PHP 進程函數
> PHP語言中實現進程相關操作的是以`pcntl_*`為前綴的函數族(pcntl應該是process control的簡稱)。
一般說來多個進程可以加速任務完成速度,但是CPU在同一個時刻只能執行一個進程,操作系統通過調度算法在多個進程之間快速輪轉CPU占用時間,弄的同一個CPU核心看起來好像同一時間真的可以支持多個進程似的然而實際上卻并不是都是假象PS唬人的幻覺;其次是多個進程之間的數據是隔離的,子進程會繼承走父進程的數據空間、堆、棧等信息,總之就是父子之間的正文段是共享的,但是存儲空間是隔離的。
## pcntl_fork() 函數創建了一個子進程
在當前進程當前位置產生分支(子進程)
>[warning] 譯注:fork是創建了一個子進程,父進程和子進程 都從fork的位置開始向下繼續執行,不同的是父進程執行過程中,得到的fork返回值為子進程 號,而子進程得到的是0。
```
echo 'master process id = ' . posix_getpid() . PHP_EOL;
// 創建一個子進程
$pid = pcntl_fork();
//父進程和子進程都會執行下面代碼
if ($pid == -1) {
//錯誤處理:創建子進程失敗時返回-1
die('could not fork');
} else if ($pid) {
//父進程會得到子進程號(就是fork出來的),所以這里是父進程執行的邏輯
echo 'parent process id = ' . posix_getpid() . PHP_EOL;
} else {
//子進程得到的$pid為0, 所以這里是子進程執行的邏輯。
echo 'child process id = ' . posix_getpid() . PHP_EOL;
}
```
> 執行順序:1、先執行主進程。2、執行子進程。3、等待子進程退出
執行結果
```bash
# php pcntl_fork.php
master process id = 20
parent process id = 20
child process id = 21
```
- 介紹
- 基礎
- Linux SOCKET編程詳解
- PHP SOCKET編程
- 1. socket 和 stream_socket
- 2. stream_socket_server 函數
- 3. stream_socket_accept 函數
- 什么是 EventLoop
- Linux 進程間通信
- 1.1 管道通信
- 系統調用
- IO多路復用
- epoll事件
- Redis IO多路復用
- select/poll/epoll介紹
- 函數接口
- pcntl 函數
- pcntl_wait 函數
- pcntl_alarm() 函數
- 高性能API社區閱讀筆記
- 子進程
- 進程回收
- 執行任務方式
- 進程監控monitor
- daemon進程
- Unix 信號
- 進程間通信
- libevent擴展
- Workerman專題
- 附錄一 調試工具
- B站Workerman服務器實戰原理解析筆記
- PHP實現一個webserver
- 其他