赞
踩
进程 = = 资源管理 + 线程
pthread_key_create(),ptread_setspecific(),pthread_getspecific()以及pthread_key_delete()
。#ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 15276 max locked memory (kbytes, -l) 65536 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 15276 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited
使用两个链表来管理这些线程栈:
用户程序调用Linux库函数,pthread_create()
;
试图根据设置用户态的栈的大小从stack_cache找出合适大小的线程栈,如果有,设置为线程栈,如果没有则从堆中申请指定大小的空间作为线程栈;
创建一个pthread实例,将这个实例放在线程栈的栈低位置,pthread中存放可当前线程的数据,如线程的私有数据,栈的大小,需要执行的函数等。
主线程调用create_thread(),create_thread()将调用clone()产生系统调用,陷入内核
将主线程的寄存器信息保存在主线程内核栈中,然后调用sys_clone()
紧接着调用do_fork():
创建task_struct,以及对应的内核栈
不需要复制进程的task_struct,共享进程的task_struct,类似于浅拷贝
维护亲缘关系:
tgid 所属进程的pid
pid 自己的进程id
如果tgid==pid,那么表示当前task是一个进程,如果tgid!=pid,表示当前task是一个线程。
这里调用clone()前,进入内核态前,保存的是主线程的栈和指令指针,按照一般的系统调用来看,
返回用户态后,恢复用户态的执行后,应该是恢复主线程的状态。但是这里clone()与一般的系统调用
不一样,clone()返回后,恢复的栈是刚刚创建的线程的栈,栈顶指针等都是指向刚刚创建的线程的栈。
线程的创建是用户空间和内核空间共同配合完成的,上述过程中前三部都是发生在用户态,旨在产生一个用户态的thread实例,后面的步骤发生在内核态,旨在产生一个内核态的thread实例,将用户态和内核态的thread实例一一对应,实际上就是一对一的线程模型。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。