rcore-os / rCore-Tutorial-Book-v3

A book about how to write OS kernels in Rust easily.
https://rcore-os.github.io/rCore-Tutorial-Book-v3/
GNU General Public License v3.0
1.23k stars 233 forks source link

rCore-Tutorial-Book-v3/chapter8/2lock #114

Open utterances-bot opened 2 years ago

utterances-bot commented 2 years ago

锁机制 — rCore-Tutorial-Book-v3 3.6.0-alpha.1 文档

https://rcore-os.github.io/rCore-Tutorial-Book-v3/chapter8/2lock.html

lindyang commented 2 years ago

riscv64-unknown-elf-gcc -o f.s -S f.c 对于线程T0、T1执行,表格最后一列为“寄存器a5”,含有“L23”的行,其值为“1”应该不正确。 因为按你给出的汇编(第22行) 22 lui a5,%hi(a) 又把a的高位地址存入a5寄存器,也就是说“L23”执行后,其值为“a的高位地址”

lindyang commented 2 years ago

用户态软件级方法实现锁 这里只列举的 2 个线程的情况, static mut flag : [i32;2] = [0,0]; // 哪个线程想拿到锁? static mut turn : i32 = 0; // 排号:轮到哪个线程? (线程 0 or 1?)

那如果是超过两个线程呢,这个 turn 怎么使用,才能表示除自己外的其它线程。 对于 turn,不管是用bit位标记,或字典表示,如果多个线程都“谦让”地礼让其它线程, 那到底谁会胜出?

peterlau123 commented 2 years ago

假设有N个线程 那么,flag是大小为N的数,turn仍为一个数值

那么此时,turn的数值选择就微妙了,简单的办法是 radom(0,N),选择是哪个就是哪个


while( flag[turn]==1 && turn!=self );
Z3ratu1 commented 2 years ago

MutexBlockinglock方法内似乎也并不能防止竞争,是因为条件竞争的源头来自于抢占式调度,而内核本身不会被抢占吗?如果按照这个方式理解,单核处理器下该实现应该是可行的,那么对于多核处理器呢?如果内核可以同时运行在多个处理器下是否上述代码仍然会产生条件竞争?而解决方案是不是内核中的锁实现要通过原子操作保证互斥呢?

huanngod commented 2 years ago

lock(mutex); // 尝试取锁 a=a+1; // 临界区,访问临界资源 a unlock(mutex); // 是否锁 (应该是释放锁)

longguzzz commented 1 year ago

// 是否锁

释放锁

不太可能约束可能在临界区的各种指令执行共享变量操作的互斥性。

(“约束互斥性”的说法有点曲折) 不太可能~约束~提供可能在临界区的各种指令执行共享变量操作的互斥性。

它也会把多个线程访问,

会被

而如果SR指令的目标地址上存在保留 记录

SC指令

互斥 是一种每个线程能看到的资源

互斥锁是一种

taotao419 commented 1 year ago

首先是Turn ,它被Ti 设置为 j ,而Tj在退出临界区之前不会对它进行修改

从代码上看, Tj只会在进入临界区之前修改Turn , 其他时候不会修改这个值. 这句话感觉没啥意义.

chestNutLsj commented 1 year ago
  1. 捉个错别字:

    有界等待 (Bounded Waiting):当线程获取锁失败的时候首先需要等待锁被释放,但这并不意味着此后它能够立即抢到被释放的锁,因为此时可能还有其他的线程也处于等待状态。

  2. 在此处可以补充说明一点,可以让读者更加领会清楚有意义的忙等的价值:

    在忙等有意义的前提下,忙等的优势是在条件成立的第一时间就能够进行响应,对于事件的响应延迟更低,实时性更好,而且不涉及开销很大的上下文切换。它的缺点则是不可避免的会浪费一部分 CPU 资源在忙等上。(不过在多处理器环境中,单个处理器的利用率不再是首要考虑的目标,响应性和整体性能才是。)

wyfcyx commented 1 year ago

在忙等有意义的前提下,忙等的优势是在条件成立的第一时间就能够进行响应,对于事件的响应延迟更低,实时性更好,而且不涉及开销很大的上下文切换。它的缺点则是不可避免的会浪费一部分 CPU 资源在忙等上。(不过在多处理器环境中,单个处理器的利用率不再是首要考虑的目标,响应性和整体性能才是。)

@chestNutLsj 第二点值得商榷,其实究竟哪个更重要也是跟场景相关的,比如在手机上就是响应性更重要,服务器上显然CPU利用率更重要。这个还需要想想在这本书里面如何去讨论。

chestNutLsj commented 1 year ago

在忙等有意义的前提下,忙等的优势是在条件成立的第一时间就能够进行响应,对于事件的响应延迟更低,实时性更好,而且不涉及开销很大的上下文切换。它的缺点则是不可避免的会浪费一部分 CPU 资源在忙等上。(不过在多处理器环境中,单个处理器的利用率不再是首要考虑的目标,响应性和整体性能才是。)

@chestNutLsj 第二点值得商榷,其实究竟哪个更重要也是跟场景相关的,比如在手机上就是响应性更重要,服务器上显然CPU利用率更重要。这个还需要想想在这本书里面如何去讨论。

@wyfcyx 确实,我的观点有些过于笼统,精细于使用场景可能有不同的顾虑。 本书的主要讨论环境是单核系统,因此这个话题作为延伸思考和资料收集,对理解现代复杂的操作系统很有帮助。

alanvirus commented 3 months ago

在线程退出时,我们需要 检查线程所有可能出现的位置并将线程控制块移除,不然就会造成内存泄漏

在分支ch8的remove_inactive_task函数中只从sleep队列和manager队列中移除了控制块,是不是应该把PCB的mutex,semaphore和condvar列表也清空一下?