首页 kernel正文

pthread中线程是怎么创建的(2)---glibc到内核

helight0 kernel 2013-04-28 64 0 thrift

在glibc中线程创建是这个文件种来定义的:nptl/pthread_create.c 创建过程为,pthread_create 调用__pthread_create_2_0, __pthread_create_2_0调用__pthread_create_2_1, 或者pthread_create直接调用__pthread_create_2_1,在由__pthread_create_2_1调用create_thread来创建。 在create_thread中,首先是设置了很多内核clone的标志,因为对内核来说每次创建都是创建一个内核级的线程或是内核级进程。 /* We rely heavily on various flags the CLONE function understands: CLONE_VM, CLONE_FS, CLONE_FILES These flags select semantics with shared address space and file descriptors according to what POSIX requires. CLONE_SIGNAL This flag selects the POSIX signal semantics. CLONE_SETTLS The sixth parameter to CLONE determines the TLS area for the new thread. CLONE_PARENT_SETTID The kernels writes the thread ID of the newly created thread into the location pointed to by the fifth parameters to CLONE. Note that it would be semantically equivalent to use CLONE_CHILD_SETTID but it is be more expensive in the kernel. CLONE_CHILD_CLEARTID The kernels clears the thread ID of a thread that has called sys_exit() in the location pointed to by the seventh parameter to CLONE. The termination signal is chosen to be zero which means no signal is sent. */ int clone_flags = (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGNAL | CLONE_SETTLS | CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID | CLONE_SYSVSEM | 0); 然后调用线程函数种的do_clone函数来发起系统调用,进行线程的创建。 int rc = ARCH_CLONE (fct, STACK_VARIABLES_ARGS, clone_flags, pd, &pd->tid, TLS_VALUE, &pd->tid); #ifndef ARCH_CLONE # define ARCH_CLONE __clone #endif __clone 在这个文件中,是一个汇编程序 ./sysdeps/unix/sysv/linux/i386/clone.S ENTRY (BP_SYM (__clone)) 在__clone函数中会调用__NR_clone movl $SYS_ify(clone),%eax #define SYS_ify(syscall_name)__NR_##syscall_name __NR_clone 在这个clone会变文件中也做了定义: #define __NR_clone 120 #define SYS_clone 120 从这里开始便发起了系统调用走向了内核了,在内核系统调用表中可以看到120对应的系统调用函数,arch/x86/kernel/syscall_table_32.S .long ptregs_sigreturn .long ptregs_clone /* 120 */ .long sys_setdomainname 在这个文件中可以看到ptregs_clone的定义,arch/x86/kernel/entry_32.S #define PTREGSCALL(name) \ ALIGN; \ ptregs_##name: \ leal 4(%esp),%eax; \ jmp sys_##name; PTREGSCALL(clone) ./arch/x86/kernel/process_32.c 中定义了 sys_clone int sys_clone(struct pt_regs *regs) 看看sys_clone其实还是调用do_fork函数,所以创建的也就是内核种的进程,这样也就和前几分析的gettid和[thread_self的区别联系到了一起

版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。