linux 线程的内核栈是独立的还是共享父进程的?
需要考证
考证结果:
其内核栈是独立的
206 static struct task_struct *dup_task_struct(struct task_struct *orig)
207 {
208 struct task_struct *tsk;
209 struct thread_info *ti;
210 int err;
211
212 prepare_to_copy(orig);
213
214 tsk = alloc_task_struct();
215 if (!tsk)
216 return NULL;
217
218 ti = alloc_thread_info(tsk);
219 if (!ti) {
220 free_task_struct(tsk);
221 return NULL;
222 }
223
224 err = arch_dup_task_struct(tsk, orig);
225 if (err)
226 goto out;
227
228 tsk->stack = ti;
229
230 err = prop_local_init_single(&tsk->dirties);
231 if (err)
232 goto out;
233
234 setup_thread_stack(tsk, orig);
。。。。。。。、 98 #ifndef __HAVE_ARCH_THREAD_INFO_ALLOCATOR
99 static inline struct thread_info *alloc_thread_info(struct task_struct *tsk)
100 {
101 #ifdef CONFIG_DEBUG_STACK_USAGE
102 gfp_t mask = GFP_KERNEL | __GFP_ZERO;
103 #else
104 gfp_t mask = GFP_KERNEL;
105 #endif
106 return (struct thread_info *)__get_free_pages(mask, THREAD_SIZE_ORDER);
107 }
108
。。。。。。
Breakpoint 2, __get_free_pages (gfp_mask=208, order=1) at mm/page_alloc.c:1670
1670 page = alloc_pages(gfp_mask, order);
(cskygdb) bt
#0 __get_free_pages (gfp_mask=208, order=1) at mm/page_alloc.c:1670
#1 0x9000f5d6 in alloc_thread_info (clone_flags=4001536, stack_start=7, regs=0x0, stack_size=715825152, child_tidptr=0x0, pid=0x0, trace=0)
at kernel/fork.c:106
#2 dup_task_struct (clone_flags=4001536, stack_start=7, regs=0x0, stack_size=715825152, child_tidptr=0x0, pid=0x0, trace=0)
at kernel/fork.c:218
#3 copy_process (clone_flags=4001536, stack_start=7, regs=0x0, stack_size=715825152, child_tidptr=0x0, pid=0x0, trace=0)
at kernel/fork.c:922
#4 0x90010a7e in do_fork (clone_flags=4001536, stack_start=715921168, regs=0x90847fb8, stack_size=0, parent_tidptr=0x2aac1be8,
child_tidptr=0x2aac1be8) at kernel/fork.c:1348
#5 0x90005c4e in csky_clone (clone_flags=<value optimized out>, newsp=<value optimized out>, parent_tidptr=<value optimized out>,
child_tidptr=0x90005c4e, tls_val=<value optimized out>, regs=<value optimized out>) at arch/csky/kernel/process.c:237
#6 0x900009d2 in system_call ()
网上的介绍:
http://www.360doc.com/content/13/0527/00/12499915_288433220.shtml
linux 线程有自己独立的内核栈吗?
首先,我们知道所有线程共享主线程的虚拟地址空间(current->mm指向同一个地址),且都有自己的用户态堆栈(共享父进程的地址空间,再在里面分配自己的独立栈,默认2M)。这是毫无疑问的,但还有一点我没搞明白,内核栈是共享还是独立的?
猜测:独立的。理由:要不然内核栈对应的thread_info中的tast_struct没有办法与每个线程对应起来,因为现在已经有多个task_struct了,但保存内核栈的thread_info(其实是thread_union联合体)中只能保存一个task_struct。所以理论上分析,虽然可以共享地址空间,但每个线程还是需要一个单独的内核栈的。看代码:
分析创建线程最终肯定会走到内核函数do_fork()中来的,所以从此函数看起。
do_fork()->copy_process()->dup_task_struct()
fork.c中dup_task_struct()的实现:
static struct task_struct *dup_task_struct(struct task_struct *orig)
{
struct task_struct *tsk;
struct thread_info *ti;
unsigned long *stackend;
int node = tsk_fork_get_node(orig);
int err; tsk = alloc_task_struct_node(node);
if (!tsk)
return NULL; ti = alloc_thread_info_node(tsk, node);/*就是这里,果然分配内核栈了*/
if (!ti)
goto free_tsk; err = arch_dup_task_struct(tsk, orig);/*这里分配task_struct结构*/
if (err)
goto free_ti; tsk->stack = ti;
...
}
线程在Linux中的实现
3.3 线程在Linux中的实现
线程机制是现代编程技术中常用的一种抽象。该机制提供了在同一程序内共享内存地址空间运行的一组线程。这些线程还可以共享打开的文件和其他资源。线 程机制支持并发程序设计技术(concurrent programming),在多处理器系统上,它也能保证真正的并行处理(parallelism)。
Linux实现线程的机制非常独特。从内核的角度来说,它并没有线程这个概念。Linux把所有的线程都当作进程来实现。内核并没有准备特别的调度 算法或是定义特别的数据结构来表征线程。相反,线程仅仅被视为一个与其他进程共享某些资源的进程。每个线程都拥有惟一隶属于自己的 task_struct,所以在内核中,它看起来就像是一个普通的进程(只是该进程和其他一些进程共享某些资源,如地址空间)。
上述线程机制的实现与Microsoft Windows或是Sun Solaris等操作系统的实现差异非常大。这些系统都在内核中提供了专门支持线程的机制(这些系统常常把线程称作轻量级进程,lightweight process)。“轻量级进程”这种叫法本身就概括了Linux在此处与其他系统的差异。在其他的系统中,相较于重量级的进程,线程被抽象成一种耗费较 少资源,运行迅速的执行单元。而对于Linux来说,它只是一种进程间共享资源的手段(Linux的进程本身就够轻了)。举个例子来说,假如我们有一个包 含四个线程的进程,在提供专门线程支持的系统中,通常会有一个包含指向四个不同线程的指针的进程描述符。该描述符负责描述像地址空间、打开的文件这样的共 享资源。线程本身再去描述它独占的资源。相反,Linux仅仅创建四个进程并分配四个普通的task_sturct结构。建立这四个进程时指定它们共享某 些资源就行了。
线程的创建和普通进程的创建类似,只不过在调用clone()的时候需要传递一些参数标志来指明需要共享的资源:
- clone(CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, 0);
 
上面的代码产生的结果和调用fork()差不多,只是父子俩共享地址空间、文件系统资源、文件描述符和信号处理程序。换个说法就是,新建的进程和它的父进程就是流行的所谓线程。
对比一下,一个普通的fork()的实现是:
- clone(SIGCHLD, 0);
 
而vfork()的实现是:
- clone(CLONE_VFORK | CLONE_VM | SIGCHLD, 0);
 
传递给clone()的参数标志决定了新创建进程的行为方式和父子进程之间共享的资源种类。表3-1列举了这些clone()用到的参数标志以及它们的作用,这些是在<linux/sched.h>中定义的。
linux 线程的内核栈是独立的还是共享父进程的?的更多相关文章
- linux线程的实现
		
首先从OS设计原理上阐明三种线程:内核线程.轻量级进程.用户线程 内核线程 内核线程就是内核的分身,一个分身可以处理一件特定事情.这在处理异步事件如异步IO时特别有用.内核线程的使用是廉价的,唯一使用 ...
 - linux线程的实现【转】
		
转自:http://www.cnblogs.com/zhaoyl/p/3620204.html 首先从OS设计原理上阐明三种线程:内核线程.轻量级进程.用户线程 内核线程 内核线程就是内核的分身,一个 ...
 - linux线程的实现(转)
		
原文:https://www.cnblogs.com/zhaoyl/p/3620204.html 首先从OS设计原理上阐明三种线程:内核线程.轻量级进程.用户线程 内核线程 内核线程就是内核的分身,一 ...
 - 【转】linux线程模型
		
一.定义 关于进程.轻量级进程.线程.用户线程.内核线程的定义,这个很容易找到,但是看完之后你可以说你懂了,但实际上你真的明白了么? 在现代操作系统中,进程支持多线程.进程是资源管理的最小单元:而线程 ...
 - Linux 线程浅析
		
进程和线程的区别与联系 在许多经典的操作系统教科书中,总是把进程定义为程序的执行实例,它并不执行什么, 只是维护应用程序所需的各种资源,而线程则是真正的执行实体. 为了让进程完成一定的工作,进程必须至 ...
 - POSIX 线程详解 一种支持内存共享的简捷工具
		
线程是有趣的 了解如何正确运用线程是每一个优秀程序员必备的素质.线程类似于进程.如同进程,线程由内核按时间分片进行管理.在单处理器系统中,内核使用时间分片来模拟线程的并发执行,这种方式和进程的相同.而 ...
 - Python 第八篇:异常处理、Socket语法、SocketServer实现多并发、进程和线程、线程锁、GIL、Event、信号量、进程间通讯
		
本节内容: 异常处理.Socket语法.SocketServer实现多并发.进程和线程.线程锁.GIL.Event.信号量.进程间通讯.生产者消费者模型.队列Queue.multiprocess实例 ...
 - linux 线程基础
		
线程基础函数 查看进程中有多少个线程,查看线程的LWP ps -Lf 进程ID(pid) 执行结果:LWP列 y:~$ ps -Lf 1887 UID PID PPID LWP C NLWP STIM ...
 - [转载]Linux 线程实现机制分析
		
本文转自http://www.ibm.com/developerworks/cn/linux/kernel/l-thread/ 支持原创.尊重原创,分享知识! 自从多线程编程的概念出现在 Linux ...
 
随机推荐
- MongoDB五种树形结构表示法
			
MongoDB五种树形结构表示法 第一种:父链接结构 db.categories.insert( { _id: "MongoDB", parent: "Databases ...
 - SequoiaDB 1.5 版本发布
			
SequoiaDB 1.5 – 2013.11.13 新特性 1. 新增聚合特性,API实现 GROUPBY, MAX 等功能: 2. 全新改版的Web管理界面: 3. 提供C#语言 ...
 - 使用GDataXML解析XML文档
			
转载自:http://blog.csdn.net/tangren03/article/details/7868246 在IOS平台上进行XML文档的解析有很多种方法,在SDK里面有自带的解析方法,但是 ...
 - Highcharts条形与柱形同时显示
			
var chart; $(function() { chart = new Highcharts.Chart({ chart: { renderTo: 'chart_combo' //关联页面元素di ...
 - GoldenGate 基础架构
			
一.Goldengate 产品家庭 Goldengate:核心产品 Goldengate Director :现已更名为Goldengate Management Pack,为Goldengate提供 ...
 - Python之回调魔法
			
Python中魔法(前后又下划线)会在对象的生命周期被回调. 借助这种回调, 可以实现AOP或者拦截器的思想. 在Python语言中提供了类似于C++的运算符重在功能:一下为Python运算符重在调用 ...
 - 【quartz】 理论知识
			
属性的介绍 1.调度器属性:分别设置调度器的实例名(instanceName) 和实例 ID (instanceId).属性 org.quartz.scheduler.instanceName 可以是 ...
 - How To Fix – Mcrypt PHP extension required in Laravel on Mac OS X (No MAMP)
			
Laravel PHP web framework requires certain libraries to function properly. One of these libraries is ...
 - Android SDK Android NDK 官方下载地址
			
Android NDK r6b Windows http://dl.google.com/android/ndk/android-ndk-r6b-windows.zip Mac OS X(intel) ...
 - android手机推送视频到服务端
			
项目需求,android手机向服务器推送视频.苦战几个星期终于实现,现记录下来以免以后忘记. 没做过Java,也没做过Android开发,只能现学现卖.在网上找了下搭建开发a ndroid环境资料, ...