天天看點

《TCP/IP網絡程式設計》第十章讀書筆記

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.

《TCP/IP網絡程式設計》第十章讀書筆記
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需謹慎。

《TCP/IP網絡程式設計》第十章讀書筆記

示例: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  
           
  1. pid:等待終止的目标子程序ID,若傳遞-1,則與wait函數相同,等待任意子程序  
  2. statloc:與wait函數的statloc參數一緻  
  3. 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;  
}