zoukankan      html  css  js  c++  java
  • 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 plaincopy在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 plaincopy在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 plaincopy在CODE上查看代码片派生到我的代码片
     
    1. #define get_file(x) atomic_inc(&(x)->f_count)  

    所以,子进程会将父进程中已经建立的socket加上引用计数。当进程中close一个socket时,只会减少引用计数,仅当引用计数为0时才会触发tcp_close。
     
    到这里,对于第一个问题的close调用自然有了结论:单线程(进程)中使用close与多线程中是一致的,但这两者与多进程的行为并不一致,多进程中共享的同一个socket必须都调用了close才会真正的关闭连接。
     
    而shutdown则不然,这里是没有引用计数什么事的,只要调用了就会去试图按需关闭连接。所以,调用shutdown与多线程、多进程无关。
  • 相关阅读:
    gradle
    1-NIO使用
    处理非正常终止的错误
    一个取消多生产者单消费者的日志线程池服务
    executes()源码
    死锁
    CyclicBarrier使用
    Semaphore
    Spring学习(4)IOC容器配置bean:定义与实例化
    在Maven上Web项目添加Spring框架
  • 原文地址:https://www.cnblogs.com/diegodu/p/4705806.html
Copyright © 2011-2022 走看看