-
Notifications
You must be signed in to change notification settings - Fork 68
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
实验四(上)题目:clone 线程时无法实现安全的栈拷贝 #106
Comments
我对该 issue 的理解不太正确,实验的确有问题 |
这应当是 fork 和 clone 语义的区别,如果是拷贝当前进程的话应当是 fork 而非 clone。如果是复制进程的话,应该可以使该进程的虚拟地址与原进程的虚拟地址相同,但对应于不同的物理地址页,此时复制栈之后就不会出现引用旧线程变量的问题,也不需要重新分配空栈,这样应该是可行的;重新分配空栈的话,应该也对应于新创建线程的 create 语义而不是 clone。 |
@wfly1998 未定义的行为并不总会导致可见的问题。 考虑以下代码(未测试): let x: i32 = 42;
let x_ref = &x;
if clone_thread() == 0 {
assert!(&x as *const _ == x_ref as *const _, "path 1");
} else {
assert!(&x as *const _ == x_ref as *const _, "path 2");
} 在不开启任何编译优化的情况下,你认为是否会有一个 |
是的,拷贝进程会完整复制虚拟地址空间,应该就没问题了 |
直接在同一地址空间复制栈还有一个危险,即使引用没有失效,也有可能出现两个mutable reference。悄无声息的发生data race,是一种implicit的unsafe。所以应该只有@losfair提出的两种方法可行,拷贝进程或者重新开一个栈……😢 |
抱歉,是我理解的错误,我以为你说的无法实现安全的栈拷贝指的是会用到 我查阅了 rCore 对 sys_clone 的实现,我发现 sys_clone 传入的参数中有新的线程指针 |
感谢指出问题,这确实是我们在沿用以前版本的实验题目时没有考虑到新版本框架的不同 题目会改为实现进程的 fork,而如果大家做了“并不安全的 clone”也不需要重新再做一次 fork。 |
突然意识到,改成 |
实验六会要求做 |
如果分配空栈 实验六的sys_open就会报错 ,所以第二种方法并不可取 |
涉及文件
https://rcore-os.github.io/rCore-Tutorial-deploy/docs/lab-4/practice-1.html
相关段落
实验四(上)对
clone()
的要求是:遇到问题
新线程的栈和寄存器内都可能有对栈上地址的引用,拷贝栈不会更新这些引用。于是在新栈上继续执行的代码对局部变量的访问会错误地引用旧栈上的地址。
建议做以下修改之一:
clone()
为拷贝当前进程而非线程。The text was updated successfully, but these errors were encountered: