注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Tsecer的回音岛

Tsecer的博客

 
 
 

日志

 
 

线程退出时如何通知等待者  

2012-01-04 22:46:09|  分类: Linux内核 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
一、线程退出
在之前的一篇博客(http://tsecer.blog.163.com/blog/static/150181720120175027358/)中说明了一个进程描述符的回收过程,其中可以看到,只有主线程有权利通知父进程整个线程组已经退出,也就宣告整个任务的结束,其它的线程(一般通过pthread_create创建)没有机会向父进程发送信号,也不能直接的wakeup父进程。但是在pthread线程库中,有时候我们又必须通过某种方法来通知其它对线程退出感兴趣的线程,例如,当线程创建之后,一个等待线程可能通过pthread_join来同步等待一个线程,也就是说,这个线程不消亡,等待着就没有勇气继续执行下去。
现在假设这个被等待的线程真的执行结束了,这个等待者将如何被唤醒呢?
二、C库实现
glibc-2.7\nptl\pthread_join.c
int
pthread_join (threadid, thread_return)
     pthread_t threadid;
     void **thread_return;
函数等待的位置:
  else
    /* Wait for the child.  */
    lll_wait_tid (pd->tid);这个等待其实最后就是执行sys_futex(WAIT)
看起来还是比较简单的吧。当然,很多看起来很简单的东西都不像它看起来的那么简单,所以这里也不能随便找个地方就开始等,这个位置也是需要精挑细选的,这个等待还要从线程的创建说起
__pthread_create_2_1--->>create_thread--->>>
  int clone_flags = (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGNAL
             | CLONE_SETTLS | CLONE_PARENT_SETTID
             | CLONE_CHILD_CLEARTID | CLONE_SYSVSEM
#if __ASSUME_NO_CLONE_DETACHED == 0
             | CLONE_DETACHED
#endif
             | 0);
do_clone--->>>
  if (ARCH_CLONE (fct, STACK_VARIABLES_ARGS, clone_flags,这里通过__clone系统调用进入内核
          pd, &pd->tid, TLS_VALUE, &pd->tid) == -1)
三、内核实现
1、位置记录
在内核中
sys_clone--->>>do_fork--->>>copy_process
    p->clear_child_tid = (clone_flags & CLONE_CHILD_CLEARTID) ? child_tidptr: NULL;
所以内核保存了ARCH_CLONE中传递的pd->tid变量的位置进入在内核中,记录在被等待线程描述符的clear_child_tid指针中。
2、唤醒执行
pthread_exit--->>sys_exit--->>do_exit--->>>exit_mm--->>>mm_release
if (tsk->clear_child_tid
        && !(tsk->flags & PF_SIGNALED)
        && atomic_read(&mm->mm_users) > 1) {
        u32 __user * tidptr = tsk->clear_child_tid;
        tsk->clear_child_tid = NULL;

        /*
         * We don't check the error code - if userspace has
         * not set up a proper pointer then tough luck.
         */
        put_user(0, tidptr);
        sys_futex(tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
    }
至于为什么在mm中执行唤醒呢?我想可能是因为这个futex是依赖于mm_struct结构的吧。
  评论这张
 
阅读(978)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017