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与多线程、多进程无关。
相关文章
相关标签/搜索