- The document discusses the process of forking and creating new processes in an operating system. It describes the key steps like allocating memory for the child process, copying resources from the parent, and starting the new process.
- Code examples are provided to demonstrate how fork is implemented at the system call level and how it is used in C programs to create new threads.
- The document also explains the data structures and functions involved in process switching and context switching between threads.
8. 0 A: 2 . 4# A:8 A A 5#
• , 8: #4 A 2 5 : (# A 7 A #4 / )
• 17 A RL15 17 A I
#ifdef __ARCH_WANT_SYS_FORK
SYSCALL_DEFINE0(fork)
{
#ifdef CONFIG_MMU
return _do_fork(SIGCHLD, 0, 0, NULL, NULL, 0);
#else
/* can not support in nommu mode */
return -EINVAL;
#endif
}
#endif
14. 8 8 / # A 8A8 87# (
• A A78 A C E A A CE 8 8 8 7# 0()
• ,.4,021 A A4 8 R HN O IL
static int
create_thread (struct pthread *pd, const struct pthread_attr *attr,
bool *stopped_start, STACK_VARIABLES_PARMS, bool *thread_ran)
{
/* */
const int clone_flags = (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SYSVSEM
| CLONE_SIGHAND | CLONE_THREAD
| CLONE_SETTLS | CLONE_PARENT_SETTID
| CLONE_CHILD_CLEARTID
| 0);
/* */
ARCH_CLONE(&start_thread, STACK_VARIABLES_PARMS, clone_flags, pd, &pd->tid, tp,
&pd->tid);
/* */
return 0;
}
15. 0 A: 2 . 4# A:8 A A 5# )
• , 8: #4 A 2 5 : (# A 7 A #4 /
• 14 15 17 A L I
SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp,
int __user *, parent_tidptr,
int __user *, child_tidptr,
unsigned long, tls)
{
return _do_fork(clone_flags, newsp, 0, parent_tidptr, child_tidptr, tls);
}
16. ) ) (
I GEA H: 0C EA GF E F EH
• N LM _ O DC > : FO
• TV 60. 1
• RS 1 , 82 1 , -6 1 , -01,6 1 , ,
17. M I : /D IH H
• IIFH D LAC EH D AF IC 0 C:D F: H C:D ED IC
• 0 2, 81
• Rx mtedV mted Sop u
• 0 2, -
• Rx mtedV mtedP S rcdhn v T
• 0 2, -/0,
• Rx mtedV mted ri_da m hNlr v T
• 0 2, 7. ,
• mted Rx mtedV Sdsgj rNm O
18. # . / , 1 77 45 2
/*
* cloning flags:
*/
#define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
#define CLONE_VM 0x00000100 /* set if VM shared between processes */
#define CLONE_FS 0x00000200 /* set if fs info shared between processes */
#define CLONE_FILES 0x00000400 /* set if open files shared between processes */
#define CLONE_SIGHAND 0x00000800 /* set if signal handlers and blocked signals shared */
/* */
#define CLONE_NEWPID 0x20000000 /* New pid namespace */
#define CLONE_NEWNET 0x40000000 /* New network namespace */
#define CLONE_IO 0x80000000 /* Clone io context */
• 5 4 5 0 1:8 : /72 7 A 07:0 17 2 / 7 A 15 2 5
• L 0
• I 0 4 /7
19. 8 , ) ( 8 12 9 8 9 8 .
• _ Ied 0 8 R A
• Ied R A
• I R . 0 8
• ed fcI ag
20. •
• 1 R L
• I R
•
• IA
•
8 , 2 , 1 00 2 . 2, ,2 ,
21. # . A 7 / , 1 75 A 2
• AA 57A 0 1 : A / 2 7 0 0 8 4 8 1 #
• R I L
long _do_fork(unsigned long clone_flags,
unsigned long stack_start,
unsigned long stack_size,
int __user *parent_tidptr,
int __user *child_tidptr,
unsigned long tls)
22. # /5A 85 1 ,:: 8 7A 5 5 54
• 7AA 8A7 2 A 1:4 :8 2: 2 8 : 45 :8 754 7 .
• A1 90 A A aI b
• _ R L
struct task_struct {
struct thread_info thread_info;
volatile long state;
void *stack;
struct mm_struct *mm;
struct mm_struct *active_mm;
pid_t pid;
pid_t tgid;
/* Filesystem information */
struct fs_struct *fs;
/* Open file information */
struct files_struct *files;
/* c */
}
23. 2 , ) ( 201 .
• I
A I
• ,3 , 3 I
R A 8
long _do_fork(unsigned long clone_flags,
unsigned long stack_start,
unsigned long stack_size,
int __user *parent_tidptr,
int __user *child_tidptr,
unsigned long tls)
{
struct task_struct *p;
/* */
p = copy_process(
clone_flags, stack_start, stack_size,
child_tidptr, NULL, trace, tls, NUMA_NO_NODE);
/* */
struct pid *pid = get_task_pid(p, PIDTYPE_PID);
long nr = pid_vnr(pid);
wake_up_new_task(p);
/* */
return nr;
}
24. 0 A: 2 . 4# A:8 A A 5# (
• , 8: #4 A 2 5 :
(# A 7 A #4 / )
• 5 1 2 1 A 4
• m Rb hf o I
di a kr
• 4 1
• p Rh_ m
e
• nl e g c L
static struct task_struct *copy_process(
unsigned long clone_flags,
unsigned long stack_start,
unsigned long stack_size,
int __user *child_tidptr, ...)
{
struct task_struct *p; int retval;
/* s */
p = dup_task_struct(current, node);
/* s */
retval = copy_fs(clone_flags, p);
if (retval)
goto bad_fork_cleanup_files;
retval = copy_mm(clone_flags, p);
if (retval)
goto bad_fork_cleanup_signal;
/* s */
return p;
}
25. N # 4 I 8 . : I
• II I :EC IE 8 L E
A E A : /
• :E M7CCt mnpus diP
U R
• : I vx, 5
I8 A7 I :I ah e lbr
• e gh ,/21 7 0 oc
y V_ diPV_ Ok
rfe ,/21 7 0 oc y
V_ diP
static int copy_mm(unsigned long clone_flags,
struct task_struct *tsk)
{
struct mm_struct *mm, *oldmm;
/* */
oldmm = current->mm;
/* */
if (clone_flags & CLONE_VM) {
mmget(oldmm);
mm = oldmm;
goto good_mm;
}
mm = dup_mm(tsk);
good_mm:
tsk->mm = mm;
tsk->active_mm = mm;
return 0;
/* */
}
26. 0 22 0. 6 6 ,
• A 61 6 8 a
• _ 2 R I A c
• d A