fork源碼概要分析

fork屬於系統調用,首先從用戶態切換到內核態,這個過程前面已經說過了,到了內核態之後就是調用sys_fork(),然後調用do_fork():

asmlinkage int sys_fork(struct pt_regs regs)
{
	return do_fork(SIGCHLD, regs.esp, &regs, 0, NULL, NULL);
}

這個過程會傳遞一些信號值和寄存器進去。


do_fork功能概要:

1、爲子進程分配pid,

2、調用copy_process()函數進行一系列的copy

3、將子進程加入進程調度隊列,等待cpu的調度

copy_process()功能概要:

1、爲子進程申請一個PCB(task_struct)

調用dup_task_struct()函數,一般分配8k的物理頁面,1k用於保存task_struct(PCB),另外一部分用作子進程的內核堆棧

	p = dup_task_struct(current);
	if (!p)
		goto fork_out;


2、對PCB進行初始化,如自旋鎖,定時器

	INIT_LIST_HEAD(&p->children);
	INIT_LIST_HEAD(&p->sibling);
	p->vfork_done = NULL;
	spin_lock_init(&p->alloc_lock);
	spin_lock_init(&p->proc_lock);

	clear_tsk_thread_flag(p, TIF_SIGPENDING);
	init_sigpending(&p->pending);


3、將父進程的拷貝內存管理mm_struct,文件描述符files,文件系統fs,信號,信號處理函數

if ((retval = copy_semundo(clone_flags, p)))
		goto bad_fork_cleanup_audit;
	if ((retval = copy_files(clone_flags, p)))
		goto bad_fork_cleanup_semundo;
	if ((retval = copy_fs(clone_flags, p)))
		goto bad_fork_cleanup_files;
	if ((retval = copy_sighand(clone_flags, p)))
		goto bad_fork_cleanup_fs;
	if ((retval = copy_signal(clone_flags, p)))
		goto bad_fork_cleanup_sighand;
	if ((retval = copy_mm(clone_flags, p)))
		goto bad_fork_cleanup_signal;
	if ((retval = copy_keys(clone_flags, p)))
		goto bad_fork_cleanup_mm;
	if ((retval = copy_namespace(clone_flags, p)))
		goto bad_fork_cleanup_keys;

這裏還對寄存器的值進行了copy和初始化,把eax的值設爲0(所以子進程返回值爲0),並設置EIP爲ret_from_fork的起始地址(子進程從此處開始執行)

retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs);
	if (retval)
		goto bad_fork_cleanup_namespace;


4、調用sched_fork()對子進程的靜態優先級初始化,並設置子進程爲TASK_RINNING狀態

sched_fork(p);



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章