添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

1.dup_task_struct函数调用位置及其作用

调用位置:  do_fork -> copy_process -> dup_task_struct

作用:复制一份task_struct结构体

2.函数主体流程

static struct task_struct *dup_task_struct(struct task_struct *orig)
	struct task_struct *tsk;
	struct thread_info *ti;
	unsigned long *stackend;
	int err;
	prepare_to_copy(orig);
	tsk = alloc_task_struct();  //创建新的子进程结构体
	if (!tsk)
		return NULL;
	ti = alloc_thread_info(tsk);
	if (!ti) {
		free_task_struct(tsk);
		return NULL;
 	err = arch_dup_task_struct(tsk, orig); //把orig中的内容完全复制给tsk,相当于*tsk = *orig
	if (err)
		goto out;
	tsk->stack = ti;
	err = prop_local_init_single(&tsk->dirties);
	if (err)
		goto out;
	setup_thread_stack(tsk, orig);   
   /*为整个thread_info结构复制,并设置指针指向
   thread_info里面有一个指向task_struct的指针 ,子进程指向子进程的,父进程指向父进程的,而现在,
   这两个thread_info中的某个指针,都指向了父进程的task_struct,所以还要使得子进程thread_info的指针指向tsk的task_struct,
   而不是 父进程的task_struct:task_thread_info(p)->task = p;*/
       clear_user_return_notifier(tsk);
	stackend = end_of_stack(tsk);
	*stackend = STACK_END_MAGIC;	/* for overflow detection */
#ifdef CONFIG_CC_STACKPROTECTOR
	tsk->stack_canary = get_random_int();
#endif
	/* One for us, one for whoever does the "release_task()" (usually parent) */
	atomic_set(&tsk->usage,2);
	atomic_set(&tsk->fs_excl, 0);
#ifdef CONFIG_BLK_DEV_IO_TRACE
	tsk->btrace_seq = 0;
#endif
	tsk->splice_pipe = NULL;
	account_kernel_stack(ti, 1);
	return tsk;
	free_thread_info(ti);
	free_task_struct(tsk);
	return NULL;

在专业高速缓冲内存上 分配task_struct,并完成初始化
在普通内存中 分配thread_info及连续的两个页面,完成初始化 将task_struct和thread_info联系起来 1.dup_task_struct函数调用位置及其作用调用位置:  do_fork -> copy_process -> dup_task_struct作用:复制一份task_struct结构体2.函数主体流程static struct task_struct *dup_task_struct(struct task_struct *orig){ struct task
一、Linux中的task_struct: 进程在内核源码中以数据结构task_struct的形式存在,其中有几个非常常见的属性字段 1、__state是进程的当前状态,-1是unrunnable,0是runnable, >0是stopped 2、Counter是进程拥有的时间片,当一个时钟中断到来,当前占有CPU的进程时间片会消耗1,进程调度函数schedule会会遍历任务队列选择时间片最大的进程上CPU 2.1、参照调度函数源码schedule可知,整体的调度策略是选择最长时间片的进程上CPU,直到进程
static struct task_struct *dup_task_struct(struct task_struct *orig) struct task_struct *tsk; //sizeof(task_struct) = 3236;这个值是通过gdb得到的, //可以看到单个的task_struct
先来看看task_struct结构体。 众所周知,task_struct结构体是用来描述进程的结构体,进程需要记录的信息都在其中,下面我们来看看其中的具体项目。结构体存储在linux/sched.h中。 具体的字段有volatile long state; void *stack; struct task_struct __rcu *real_parent; struct task_s
相关函数与结构体 进程创建的do_fork中会调用copy_process函数,这个函数会调用 dup_task_struct 函数 \linux-4.13.16\kernel\fork.c dup_task_struct函数 \linux-4.13.16\kernel\fork.c dup_task_struct 调用函数 alloc_task_struct_node,分配一个 task_struct 对象,用于复制task_struct alloc_task_struct_
linux内核中有个编译选项CC_STACKPROTECTOR用来开启GCC的stack-protector功能, 这个功能是在GCC4.1版本中引入,用来检测栈是否遭到溢出攻击。 目前我们用的版本中开启了这两个选项CONFIG_CC_STACKPROTECTOR、CONFIG_CC_STACKPROTECTOR_REGULAR。 编译器栈溢出保护原理: 函数栈存储结构,从
init_dup函数Linux内核中的一个函数,其作用是复制一个打开文件描述符的副本。通常在多进程并发的场景中使用,可以让多个进程同时操作同一个文件,而不会相互影响。 具体来说,init_dup函数会首先查找当前进程中与给定文件描述符fd相对应的打开文件对象,然后创建一个新的文件描述符fd2,并将fd对应的文件对象复制一份给fd2。同时,fd2所属的文件表也会被更新,这样fd2和fd就可以独立操作相同的文件对象了。 在Linux内核的代码实现中,init_dup函数有以下代码: int init_dup(struct file *file, unsigned int flags) struct file *newfile = NULL; int fd; newfile = kmem_cache_alloc(file_cachep, GFP_KERNEL); if (!newfile) return -ENOMEM; fd_install(fd, newfile); fd_install()函数是一个内部函数,用于将file所代表的文件对象添加到进程的文件描述符表中,并返回一个新的文件描述符。 return fd; 该函数会首先使用kmem_cache_alloc函数从文件对象缓存中分配一个新的文件对象,然后通过fd_install函数将该文件对象添加到当前进程的文件描述符表中。最后返回该文件描述符的值。 总之,init_dup函数Linux内核中非常重要的一个函数,在多进程并发操作文件的情况下发挥着重要的作用。其使用也非常广泛,可以在内核中的各种文件系统和设备驱动中看到它的身影。