【linux kernel】start_kernel函数详解系列之fork_init

start_kernel函数详解系列之【fork_init】
一、开篇小聊

start_kernel()中会调用fork_init()函数,该函数定义在(/kernel/fork.c)文件中:

void __init fork_init(void)
{
#ifndef CONFIG_ARCH_TASK_STRUCT_ALLOCATOR
#ifndef ARCH_MIN_TASKALIGN
#define ARCH_MIN_TASKALIGN	L1_CACHE_BYTES
#endif
	/* create a slab on which task_structs can be allocated */
	task_struct_cachep =
		kmem_cache_create("task_struct", sizeof(struct task_struct),
			ARCH_MIN_TASKALIGN, SLAB_PANIC | SLAB_NOTRACK, NULL);
#endif

	/* do the arch specific task caches init */
	arch_task_cache_init();

	set_max_threads(MAX_THREADS);

	init_task.signal->rlim[RLIMIT_NPROC].rlim_cur = max_threads/2;
	init_task.signal->rlim[RLIMIT_NPROC].rlim_max = max_threads/2;
	init_task.signal->rlim[RLIMIT_SIGPENDING] =
		init_task.signal->rlim[RLIMIT_NPROC];
}

下文,就来分析一下该函数。

首先,会调用kmem_cache_create()函数分配task_struct_cachepslab描述符,这部分操作由CONFIG_ARCH_TASK_STRUCT_ACLLOCATOR内核配置宏来管控,如果内核中没有定义该宏定义,那么将不会进行task_struct_cachep slab内存分配、释放等操作,如下代码:

#ifndef CONFIG_ARCH_TASK_STRUCT_ALLOCATOR
#ifndef ARCH_MIN_TASKALIGN
#define ARCH_MIN_TASKALIGN	L1_CACHE_BYTES
#endif
	/* create a slab on which task_structs can be allocated */
	task_struct_cachep =
		kmem_cache_create("task_struct", sizeof(struct task_struct),
			ARCH_MIN_TASKALIGN, SLAB_PANIC | SLAB_NOTRACK, NULL);
#endif

接着,会计算内核中允许的默认最大线程数,,如下代码:

set_max_threads(MAX_THREADS);

其中MAX_THREADS宏定义如下:

#define FUTEX_TID_MASK  0x3fffffff
#define MAX_THREADS     FUTEX_TID_MASK

fork_init()函数的最后,会初始化信号handler,如下代码片段:

init_task.signal->rlim[RLIMIT_NPROC].rlim_cur = max_threads/2;
init_task.signal->rlim[RLIMIT_NPROC].rlim_max = max_threads/2;
init_task.signal->rlim[RLIMIT_SIGPENDING] =
        init_task.signal->rlim[RLIMIT_NPROC];

这里出现了init_task这个全局量。init_task是struct task_struct结构的一个实例,该结构中包含信号字段,用于表示信号处理程序。在上述代码中的前2行,会设置当前(rlim_cur)和最大资源(rlim_max)限制。每个进程都有一组与其相关的资源限制。这些限制指定了当前进程可以使用的资源数量。rlim是资源控制的极限,其结构定义如下:

struct rlimit {
        __kernel_ulong_t        rlim_cur;
        __kernel_ulong_t        rlim_max;
};

在linux shell命令行下输入cat /proc/self/limits命令,可查看内核中的资源控制数。如下图所示:
在这里插入图片描述

这里有一个测试,如果写一个linux的测试程序:在一个函数中定义一个“超级大”的数组,编译运行,linux内核会有怎样的反应呢?从上图中“Max stack size”一栏可见,内核限制了最大的stack大小,约为8M,如果我们的数组大小超过了这个值,就有问题啦…


搜索关注【嵌入式小生】wx公众号获取更多精彩内容。
请添加图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

iriczhao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值