1. 并發伺服器端實作模型和方法:
a. 多程序伺服器:通過建立多個程序提供服務
b. 多路複用伺服器:通過捆綁并統一管理IO對象提供服務(select和epoll)
c. 多線程伺服器:通過生成與用戶端等量的線程提供服務
2. 通過fork函數建立程序:複制正在運作的調用fork函數的程序,複制相同的記憶體空間。兩個程序都執行fork函數以後的語句
#include <unistd.h>
pid_t fork(void); // 成功時傳回程序ID,失敗時傳回-1.
父程序Parent Prcess:fork函數傳回子程序ID
子程序Child Process:fork函數傳回0.
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiclRnblN0LclHdpZXYyd2LcBzNvwVZ2x2bzNXak9CX90TQNNkRrFlQKBTSvwFbslmZvwFMwQzLcVmepNHdu9mZvwFVywUNMZTY18CX052bm9CX4VEVNhXRU1UdWJDZ1ZlMkZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39zM2YDOzQjMxEzMwIDM3EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
1. #include <stdio.h>
2. #include <unistd.h>
3.
4. int gval = 10;
5. int main(int argc, char *argv[]){
6. pid_t pid;
7. int lval = 20;
8.
9. gval++;
10. lval += 5;
11.
12. pid = fork();
13.
14. if(pid == 0){
15. //child
16. gval += 2;
17. lval += 2;
18. }else{
19. gval -= 2;
20. lval -= 2;
21. }
22.
23. if(pid == 0){
24. printf("child gval = %d, lval = %d \n",gval,lval);
25. }else{
26. printf("parent gval = %d, lval = %d \n",gval,lval);
27. }
28. return 0;
29. }
3. 僵死Zombie程序:程序已死,但仍舊占用系統資源
a. 子程序終止方式:exit函數傳遞的參數和執行return并傳回值。
b. 僵死程序的産生:exit的傳遞值和return傳回值會傳遞給作業系統,作業系統不會銷毀子程序,直到這些值傳遞到父程序。
c. 如何傳遞值到父程序:作業系統不會主動把值傳遞到父程序,而是父程序主動請求,函數調用。如果父程序不主動請求,則子程序會一直處于僵死狀态,是以父程序要負責收回子程序。
4. 利用wait銷毀僵死程序:父程序主動請求擷取子程序的傳回值。
#include <sys/wait.h>
pid_t wait(int * statloc); //成功時傳回終止的子程序ID,失敗傳回-1
子程序終止參數儲存在wait的參數中,裡面還有其他資訊,需要通過宏分離有效值。
WIFEXITED:子程序注冊終止,傳回TRUE
WEXITSTATUS:傳回子程序的傳回值
調用wait函數時,如果沒有已終止的子程序,那麼程式blocking,直到有子程序終止,是以調用wait需謹慎。
示例:wait銷毀子程序
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
int main(int argc, char *argv[]){
int status;
pid_t pid;
pid = fork();
if(pid == 0){
return 3;
}else{
printf("Child1 PID :%d \n",pid);
pid = fork();
if(pid == 0){
exit(7);
}else {
printf("Child2 PID :%d \n",pid);
wait(&status);
if(WIFEXITED(status)){
printf("Child one : %d \n",WEXITSTATUS(status));
}
wait(&status);
if(WIFEXITED(status)){
printf("Child two : %d \n",WEXITSTATUS(status));
}
sleep(5);
}
}
return 0;
}
5. waitpid函數銷毀僵死程序
#include <sys/wait.h>
pid_t waitpid(pid_t pid, int * statloc, int options); //成功時傳回終止子程序ID,失敗傳回-1
- pid:等待終止的目标子程序ID,若傳遞-1,則與wait函數相同,等待任意子程序
- statloc:與wait函數的statloc參數一緻
- options:傳遞頭檔案sys/wait.h中聲明的常量WNOHANG,即使沒有終止子程序也不會阻塞,而是傳回0并退出函數
示例waitpid銷毀子程序:
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main(int argc, char *argv[]){
int status;
pid_t pid;
pid = fork();
if(pid == 0){
sleep(5);
return 24;
}else{
while(!waitpid(-1,&status,WNOHANG)){
sleep(1);
puts("sleep 1sec.");
}
if(WIFEXITED(status)){
printf("child send %d \n",WEXITSTATUS(status));
}
}
return 0;
}