Chinaunix首页 | 论坛 | 博客
  • 博客访问: 13296511
  • 博文数量: 2005
  • 博客积分: 11986
  • 博客等级: 上将
  • 技术积分: 22365
  • 用 户 组: 普通用户
  • 注册时间: 2007-05-17 13:56
文章分类

全部博文(2005)

文章存档

2014年(2)

2013年(2)

2012年(16)

2011年(66)

2010年(368)

2009年(743)

2008年(491)

2007年(317)

分类: LINUX

2010-11-12 15:49:40

android中库bionic线程函数pthread_create的具体执行流程

int pthread_create(pthread_t *thread_out, pthread_attr_t const * attr,
                   void *(*start_routine)(void *), void * arg)
{
......
    // Create a mutex for the thread in TLS_SLOT_SELF to wait on once it starts so we can keep
    // it from doing anything until after we notify the debugger about it
    start_mutex = (pthread_mutex_t *) &tls[TLS_SLOT_SELF];
    pthread_mutex_init(start_mutex, NULL); // 初始化thread启动锁
    pthread_mutex_lock(start_mutex); // 获取thread的启动锁,clone返回
// 之后下面的__thread_entryh函数将因为调用pthread_mutex_lock(start_mutex);而被pending
// 直到pthread_create函数退出时调用下面第10行的pthread_mutex_unlock(start_mutex);解锁
// 函数,__thread_entryh函数才能获取启动锁,进而开始执行start_routine函数
// 所以我们可以看到函数pthread_create一旦返回,线程即开始自动执行[luther.gliethttp]

    tls[TLS_SLOT_THREAD_ID] = thread;

    tid = __pthread_clone((int(*)(void*))start_routine, tls,
                CLONE_FILES | CLONE_FS | CLONE_VM | CLONE_SIGHAND
                | CLONE_THREAD | CLONE_SYSVSEM | CLONE_DETACHED,
                arg); // 调用__pthread_clone函数swi陷入内核让内核执行实际clone操作
......
    // Let the thread do it's thing
    pthread_mutex_unlock(start_mutex); // pthread_create函数执行完毕,
// 那么我们在这里释放启动锁,这样下面的__thread_entry将获取到启动锁而
// 正常启动pthread_create函数传入的参数处理函数start_routine[luther.gliethttp]

    *thread_out = (pthread_t)thread;
    return 0;
}
==> __pthread_clone该函数位于bionic/libc/arch-arm/bionic/clone.S
    .text
    .type __pthread_clone, #function
    .global __pthread_clone
    .align 4

__pthread_clone:
......
#if __ARM_EABI__
    stmfd   sp!, {r4, r7}
    ldr     r7, =__NR_clone
    swi     #0 swi软中断陷入内核,让内核执行clone操作
#else
    swi     #__NR_clone
#endif
......
b       __thread_entry swi返回之后执行该函数
......
==> __thread_entry该函数位于bionic/libc/bionic/pthread.c
/*
 * This trampoline is called from the assembly clone() function
 */
void __thread_entry(int (*func)(void*), void *arg, void **tls)
{
    int retValue;
    pthread_internal_t * thrInfo;

    // Wait for our creating thread to release us. This lets it have time to
    // notify gdb about this thread before it starts doing anything.
    pthread_mutex_t * start_mutex = (pthread_mutex_t *)&tls[TLS_SLOT_SELF];
    pthread_mutex_lock(start_mutex); // 直到pthread_create函数
// 退出时执行pthread_mutex_unlock(start_mutex);这里的启动锁才能正常获取到,进而该线程
// 开始继续执行下面的操作,完成正常启动工作[luther.gliethttp]
    pthread_mutex_destroy(start_mutex);

    thrInfo = (pthread_internal_t *) tls[TLS_SLOT_THREAD_ID];

    __init_tls( tls, thrInfo );

    pthread_exit( (void*)func(arg) );
}
阅读(4719) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2010-11-14 14:44:44

很好的, 收藏了 推荐一个博客,提供很多免费软件编程电子书下载: http://free-ebooks.appspot.com