tcp 多線程與多進程調用close

http://blog.csdn.net/russell_tao/article/details/13092727數據結構

 

 

你們知道,所謂線程其實就是「輕量級」的進程。建立進程只能是一個進程(父進程)建立另外一個進程(子進程),子進程會複製父進程的資源,這裏的」複製「針對不一樣的資源其意義是不一樣的,例如對內存、文件、TCP鏈接等。建立進程是由clone系統調用實現的,而建立線程時一樣也是clone實現的,只不過clone的參數不一樣,其行爲也很不一樣。這個話題是很大的,這裏咱們僅討論下TCP鏈接。
在clone系統調用中,會調用方法copy_files來拷貝文件描述符(包括socket)。建立線程時,傳入的flag參數中包含標誌位CLONE_FILES,此時,線程將會共享父進程中的文件描述符。而建立進程時沒有這個標誌位,這時,會把進程打開的全部文件描述符的引用計數加1,即把file數據結構的f_count成員加1,以下:
[cpp]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. static int copy_files(unsigned long clone_flags, struct task_struct * tsk)  
  2. {  
  3.     if (clone_flags & CLONE_FILES) {  
  4.         goto out;//建立線程  
  5.     }  
  6.     newf = dup_fd(oldf, &error);  
  7. out:  
  8.     return error;  
  9. }  

再看看dup_fd方法:
[cpp]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. static struct files_struct *dup_fd(struct files_struct *oldf, int *errorp)  
  2. {  
  3.     for (i = open_files; i != 0; i--) {  
  4.         struct file *f = *old_fds++;  
  5.         if (f) {  
  6.             get_file(f);//建立進程  
  7.         }  
  8.     }  
  9. }  

get_file宏就會加引用計數。
[cpp]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. #define get_file(x) atomic_inc(&(x)->f_count)  

因此,子進程會將父進程中已經創建的socket加上引用計數。當進程中close一個socket時,只會減小引用計數,僅當引用計數爲0時纔會觸發tcp_close。
 
到這裏,對於第一個問題的close調用天然有告終論:單線程(進程)中使用close與多線程中是一致的,但這二者與多進程的行爲並不一致,多進程中共享的同一個socket必須都調用了close纔會真正的關閉鏈接。
 
而shutdown則否則,這裏是沒有引用計數什麼事的,只要調用了就會去試圖按需關閉鏈接。因此,調用shutdown與多線程、多進程無關。
相關文章
相關標籤/搜索