Closed retrhelo closed 3 years ago
我查询了clone()
的手册,上面是这么说的:
When the fn(arg) function returns, the child process terminates. The integer returned by fn is the exit status for the child process. The child process may also terminate explicitly by calling exit(2) or after receiving a fatal signal.
手册里说,return的值即为子线程退出的状态。 由于clone创建的子线程有自己的栈,所以子线程脱离自己的栈,应该不会产生段错误。
是的,在仔细地分析了测试用例之后我发现这样确实是正确的。因为测试用例中使用的clone()
实际上是SYS_clone系统调用的封装。在clone()
调用了函数__clone
,这个函数才是真正的系统调用,其行为与Linux中的fork()
相似。这段代码是这样写的
# __clone(func, stack, flags, arg, ptid, tls, ctid)
# a0, a1, a2, a3, a4, a5, a6
# syscall(SYS_clone, flags, stack, ptid, tls, ctid)
# a7 a0, a1, a2, a3, a4
.global __clone
.type __clone, %function
__clone:
# Save func and arg to stack
addi a1, a1, -16
sd a0, 0(a1)
sd a3, 8(a1)
# Call SYS_clone
mv a0, a2
mv a2, a4
mv a3, a5
mv a4, a6
li a7, 220 # SYS_clone
ecall
beqz a0, 1f
# Parent
ret
# Child
1: ld a1, 0(sp)
ld a0, 8(sp)
jalr a1
# Exit
li a7, 93 # SYS_exit
ecall
对于子进程,其在SYS_clone调用之后会进入1:
开始的分支,在这里会调用之前通过clone()
传入的函数指针fn
,并在fn
返回后调用SYS_exit,从而结束子进程。
注意到测试用例
clone.c
中的子线程的代码如下但是作为子线程而言最后return的意义显得不那么明确,子线程应该返回何处?私以为子线程在执行结束后应该结束当前进程,以便父进程能够从wait()调用中离开。所以我认为子线程最后调用exit()系统调用而非return或许是一个更合适的写法? 下面这篇文章也有提到子线程不应该使用return作为结束代码