Read/Write Lock

读者优先算法

设置两个互斥信号量:rwmutex 用于写者与其他读者/写者互斥的访问共享数据                     rmutex  用于读者互斥的访问读者计数器readcount

var rwmutex, rmutex  semaphore := 1,1 
int readcount = 0; 
cobegin
       readeri begin  // i=1,2,….
              P(rmutex);
              Readcount++;
              If (readcount == 1) P(rwmutex);
              V(rmutex);
              读数据;
              P(rmutex);
              Readcount--;
              If (readcount == 0) V(rwmutex);
              V(rmutex);
       End
       Writerj begin // j = 1,2,….
              P(rwmutex);
              写更新;
              V(rwmutex);
       End 
Coend 

写者优先:

条件:

1)多个读者可以同时进行读

2)写者必须互斥(只允许一个写者写,也不能读者写者同时进行)

3)写者优先于读者(一旦有写者,则后续读者必须等待,唤醒时优先考虑写者)

1:如果读者数是固定的,我们可采用下面的算法:

rwmutex:用于写者与其他读者/写者互斥的访问共享数据 rmutex 该信号量初始值设为10,表示最多允许10个读者进程同时进行读操作

var rwmutex, rmutex semaphore := 1,10

cobegin       

readeri begin  // i=1,2,….              

P(rwmutex);  //读者、写者互斥              

P(rmutex);              

V(rwmutex);  // 释放读写互斥信号量,允许其它读、写进程访问资源               读数据;              

V(rmutex);       

End             

Writerj begin // j = 1,2,….              

P(rwmutex);              

For (i=1;i<=10;i++) P(rmutex); //禁止新读者,并等待已进入的读者退出               写更新;              

For (i=1;i<=10;i++) V(rmutex); // 恢复允许rmutex 值为10              

V(rwmutex);       

End

Coend

 

2:如果读者数不固定,采用下面的算法:

设置三个互斥信号量:

rwmutex 用于写者与其他读者/写者互斥的访问共享数据                   

rmutex  用于读者互斥的访问读者计数器readcount                                                  

nrmutex 用于写者等待已进入读者退出,所有读者退出前互斥写操作

var rwmutex, rmutexnrmutex semaphore := 111 int readcount = 0;

cobegin        readeri begin  // i=1,2,….              

P(rwmutex);              

P(rmutex);              

Readcount++;              

If (readcount == 1) P(nrmutex); //有读者进入,互斥写操作              

V(rmutex);              

V(rwmutex); // 及时释放读写互斥信号量,允许其它读、写进程申请资源               读数据;              

P(rmutex);              

Readcount--;              

If (readcount == 0) V(nrmutex); //所有读者退出,允许写更新              

V(rmutex);       

End

Writerj begin // j = 1,2,….              

P(rwmutex);  // 互斥后续其它读者、写者              

P(nrmutex);  //如有读者正在读,等待所有读者读完               写更新;              

V(nrmutex);   //允许后续新的第一个读者进入后互斥写操作              

V(rwmutex);  //允许后续新读者及其它写者       

End Coend

你遇到的是一条 **编译警告**,不是错误,但为了代码健壮性和避免潜在问题,我们来分析并解决它。 --- ## ❗ 警告内容: ``` /home/332641/IMOU/SmartLock/Kernel/Linux5.10AD100/driver/log_to_file.c:42:16: warning: 'hooked_tty_write' defined but not used [-Wunused-function] ``` ### ✅ 含义解释: - 你定义了函数 `hooked_tty_write()`; - 但在整个模块中,这个函数没有被任何地方调用; - 因此编译器发出警告:函数定义了但未使用; - 由于 `-Werror`(将警告视为错误),这会导致编译失败。 --- ## ✅ 为什么会出现这个警告? 从你的 Makefile 和编译输出来看,你正在编译一个内核模块 `log_to_file.ko`。这个模块的目的是 hook `tty_write` 函数并记录输出到缓冲区。 但: - `hooked_tty_write` 是用于替换原始 `tty_write` 的钩子函数; - 如果你没有在 `log_all_console_init()` 中将它赋值给 `orig_tty_write`,那么它就不会被调用; - 或者你已经注释掉了修改函数指针的代码,导致它未被使用; - 因此编译器提示未使用函数。 --- ## ✅ 如何修复? ### ✅ 方法一:确保 `hooked_tty_write` 被使用 确保你有如下代码在 `log_all_console_init()` 中: ```c orig_tty_write = (tty_write_t)kallsyms_lookup_name("tty_write"); if (!orig_tty_write) { pr_err("Failed to find tty_write symbol\n"); return -EINVAL; } // 替换函数指针 unsigned long cr0 = read_cr0(); write_cr0(cr0 & (~0x10000)); // 清除写保护 *(unsigned long *)orig_tty_write = (unsigned long)hooked_tty_write; write_cr0(cr0); // 恢复写保护 ``` 如果你没有使用这段代码(比如你注释掉了),那 `hooked_tty_write` 就不会被使用,自然会报这个警告。 --- ### ✅ 方法二:如果确实不需要 `hooked_tty_write` 如果你只是测试代码,或者暂时不需要 hook `tty_write`,可以安全地 **删除或注释掉这个函数**。 ### ✅ 删除函数示例: ```c // 删除整个函数 // static ssize_t hooked_tty_write(...) { ... } ``` --- ### ✅ 方法三:抑制未使用警告(不推荐) 如果你保留函数但不想看到警告,可以使用 `__attribute__((unused))`: ```c static ssize_t __attribute__((unused)) hooked_tty_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { ... } ``` 这样编译器就不会报错,但你还是要确保这个函数确实暂时不需要使用。 --- ## ✅ 推荐做法总结 | 场景 | 推荐操作 | |------|-----------| | 需要 hook tty_write | 确保函数被赋值并使用 | | 暂时不使用 | 删除或注释该函数 | | 保留函数但不想报错 | 使用 `__attribute__((unused))` 抑制警告 | --- ## ✅ 示例修复后的关键代码段 ```c static int __init log_all_console_init(void) { // 获取 tty_write 地址 orig_tty_write = (tty_write_t)kallsyms_lookup_name("tty_write"); if (!orig_tty_write) { pr_err("Failed to find tty_write symbol\n"); return -EINVAL; } // 修改写保护并替换函数指针 unsigned long cr0 = read_cr0(); write_cr0(cr0 & (~0x10000)); *(unsigned long *)orig_tty_write = (unsigned long)hooked_tty_write; write_cr0(cr0); // 其他初始化代码... } ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值