try_module_get和module_put

本文详细解析了Linux内核中的两个关键模块管理函数try_module_get和module_put的实现原理及使用方法。通过对比不同版本的Linux内核源码,展示了这些函数如何帮助维护模块的引用计数,并给出具体的应用实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

try_module_get

注解:

        1>位置:/linux/kernel/module.c

        2>声明:static inline int  try_module_get(structmodule *module)

        3>功能:判断module模块是否处于活动状态,然后通过local_inc()宏将该模块的引用计数加1

        4>返回值:

linux-2.6中返回值是一个整数,如果该模块处于活动状态且对它引用计数加1操作正确则返回1,否则返回0

linux-3.7.5中返回值是一个bool量,正确返回true,错误返回false!

实现方式Linux-2.6

static inline int try_module_get(struct module *module)
{
    int ret = 1;

    if (module) {
        unsigned int cpu = get_cpu();
        if (likely(module_is_live(module))) {
            local_inc(__module_ref_addr(module, cpu));
            trace_module_get(module, _THIS_IP_,
                local_read(__module_ref_addr(module, cpu)));
        }   
        else
            ret = 0;
        put_cpu();
    }   
    return ret;
}

实现方式Linux-3.7.5中

bool try_module_get(struct module *module)
{
    bool ret = true;

    if (module) {
        preempt_disable();

        if (likely(module_is_live(module))) {
            __this_cpu_inc(module->refptr->incs);
            trace_module_get(module, _RET_IP_);
        } else 
            ret = false;

        preempt_enable();
    }    
    return ret; 
}
EXPORT_SYMBOL(try_module_get);

module_put

注解:

     1>声明:

Linux-3.7.5中void module_put(struct module *module)

Linux-2.6中static inline void module_put(struct module *module) 

2>功能:使指定的模块使用量减一

实现方式Linux-2.6中,是空的   我很不解,求高手解释!

static inline void module_put(struct module *module)  ///不解!!
{
}


Linux-3.7.5中

void module_put(struct module *module)
{
    if (module) {
        preempt_disable();
        smp_wmb(); /* see comment in module_refcount */
        __this_cpu_inc(module->refptr->decs);

        trace_module_put(module, _RET_IP_);
        /* Maybe they're waiting for us to drop reference? */
        if (unlikely(!module_is_live(module)))
            wake_up_process(module->waiter);
        preempt_enable();
    }    
}
EXPORT_SYMBOL(module_put);

这两个函数的使用实例,hello模块init函数

/*模块初始化函数*/
static int __init hello_init(void)
{
        printk("<0>module_refcount(module):%d\n",module_refcount(THIS_MODULE));
        try_module_get(THIS_MODULE);

        printk("<0>module_refcount(module):%d\n",module_refcount(THIS_MODULE));
        module_put(THIS_MODULE);
        printk("<0>module_refcount(module):%d\n",module_refcount(THIS_MODULE));
        return 0;
}

打印的结果

[root@root hello模块]# 
Message from syslogd@localhost at Feb  2 09:07:45 ...
 kernel:module_refcount(module):1

Message from syslogd@localhost at Feb  2 09:07:45 ...
 kernel:module_refcount(module):2
 
Message from syslogd@localhost at Feb  2 09:07:45 ...
 kernel:module_refcount(module):1

由上面的程序可以看出来在模块加载的过程中,模块的使用量就是1了,然后用try_module_get把使用量变为2,再使用module_put把使用量变为1,加载完成后使用量为0
开始写程序的时候把module_put写在了__eixt中,导致加载了模块使用量一直为1,无法卸载只能重启!后来才知道rmmod是在调用module_exit之前检查模块的引用计数的,所以在exit之前就应该要module_put释放引用计数,这样一来把module_put写在init里面就可以解决了!

修改问题:未解析的引用 'StrictEventBus'未解析的引用 'LotteryCoordinator'未解析的引用 'AnalysisModule'未解析的引用 'Module4'未解析的引用 'StrictEventBus'未解析的引用 'LotteryCoordinator'未解析的引用 'AnalysisModule'第二个问题,事件C号码池既是前面模块1,模块2,模块3,模块4的数据接收者,又是模块5的数据传输者,具有双重身份,它的目的是收集前面模块传递过来的数据,打包又传递给模块5.在这里没有代码反应出来。第三个问题,不要出现数据,这样会影响数据分析的真实性。# ==================== 增强版事件总线 ==================== class EnhancedEventBus(StrictEventBus): """增强版事件总线(增加模块路由功能)""" def _process(self): while True: self._route_events('module_channel') time.sleep(0.01) def _route_events(self, channel_name: str): try: while not self.channels[channel_name].empty(): event = self.channels[channel_name].get_nowait() # 新增路由逻辑 if event.get('module') == '模块3': self._handle_module3_event(event) elif event.get('module') == '模块4': self._handle_module4_event(event) else: self.channels['notification_channel'].put(event) self.channels[channel_name].task_done() except queue.Empty: pass def _handle_module3_event(self, event): """专用模块3事件处理""" processed_event = { **event, 'metadata': {'handled_by': 'module3_handler'} } self.channels['notification_channel'].put(processed_event) def _handle_module4_event(self, event): """专用模块4事件处理""" processed_event = { **event, 'metadata': {'handled_by': 'module4_handler'} } self.channels['notification_channel'].put(processed_event) # ==================== 改进版号码池 ==================== class EnhancedNumberPool(NumberPool): """增强版号码池(支持多模块处理)""" def _register_handlers(self): bus = EnhancedEventBus() bus.channels['module_channel'].put = self._process_module_data # 注册模块3处理器 bus.channels['module_channel'].put_module3 = self._process_module3_data # 注册模块4处理器 bus.channels['module_channel'].put_module4 = self._process_module4_data def _process_module3_data(self, event: dict): """处理模块3数据""" fronts = event.get('data', {}).get('front_area', []) backs = event.get('data', {}).get('back_area', []) print(f"接收模块3数据 - 前区: {fronts} 后区: {backs}") self._store_module3_data(fronts, backs) def _process_module4_data(self, event: dict): """处理模块4数据""" analysis_data = event.get('analysis_result', {}) print("接收模块4趋势分析数据:") print(json.dumps(analysis_data, indent=2)) self._store_module4_data(analysis_data) def _store_module3_data(self, fronts, backs): """存储模块3数据""" with open(self.storage_path, 'a') as f: record = { 'timestamp': time.time(), 'type': 'module3', 'data': { 'fronts': fronts, 'backs': backs } } f.write(json.dumps(record) + '\n') def _store_module4_data(self, analysis_data): """存储模块4数据""" with open(self.storage_path, 'a') as f: record = { 'timestamp': time.time(), 'type': 'module4', 'data': analysis_data } f.write(json.dumps(record) + '\n') # ==================== 模块协调器 ==================== class EnhancedLotteryCoordinator(LotteryCoordinator): """增强版协调器(支持完整模块注册)""" def __init__(self): super().__init__() self._init_module_handlers() def _init_module_handlers(self): """初始化模块专用处理器""" # 模块3事件处理器 self.modules['module3'].handler = threading.Thread( target=self._handle_module3_events, daemon=True ) self.modules['module3'].handler.start() # 模块4事件处理器 self.modules['module4'].handler = threading.Thread( target=self._handle_module4_events, daemon=True ) self.modules['module4'].handler.start() def _handle_module3_events(self): """处理模块3事件流""" bus = EnhancedEventBus() while True: try: event = bus.channels['module_channel'].get(timeout=1) if event.get('module') == '模块3': print("处理模块3事件:", event) self.pool._process_module3_data(event) except queue.Empty: continue def _handle_module4_events(self): """处理模块4事件流""" bus = EnhancedEventBus() while True: try: event = bus.channels['module_channel'].get(timeout=1) if event.get('module') == '模块4': print("处理模块4事件:", event) self.pool._process_module4_data(event) except queue.Empty: continue # ==================== 模块实现 ==================== class Module3(AnalysisModule): """增强版模块3实现""" def submit_following_analysis(self, analysis_data: dict): """提交跟随分析结果""" super().submit({ 'type': 'following_analysis', 'data': analysis_data }) class Module4(Module4): """增强版模块4实现""" def submit_trend_analysis(self, analysis_data: dict): """提交趋势分析结果""" super().submit_analysis({ 'type': 'trend_analysis', 'data': analysis_data }) # ==================== 增强版事件总线 ==================== class EnhancedEventBus(StrictEventBus): """增强版事件总线(增加模块路由功能)""" def _process(self): while True: self._route_events('module_channel') time.sleep(0.01) def _route_events(self, channel_name: str): try: while not self.channels[channel_name].empty(): event = self.channels[channel_name].get_nowait() # 新增路由逻辑 if event.get('module') == '模块3': self._handle_module3_event(event) elif event.get('module') == '模块4': self._handle_module4_event(event) else: self.channels['notification_channel'].put(event) self.channels[channel_name].task_done() except queue.Empty: pass def _handle_module3_event(self, event): """专用模块3事件处理""" processed_event = { **event, 'metadata': {'handled_by': 'module3_handler'} } self.channels['notification_channel'].put(processed_event) def _handle_module4_event(self, event): """专用模块4事件处理""" processed_event = { **event, 'metadata': {'handled_by': 'module4_handler'} } self.channels['notification_channel'].put(processed_event) # ==================== 改进版号码池 ==================== class EnhancedNumberPool(NumberPool): """增强版号码池(支持多模块处理)""" def _register_handlers(self): bus = EnhancedEventBus() bus.channels['module_channel'].put = self._process_module_data # 注册模块3处理器 bus.channels['module_channel'].put_module3 = self._process_module3_data # 注册模块4处理器 bus.channels['module_channel'].put_module4 = self._process_module4_data def _process_module3_data(self, event: dict): """处理模块3数据""" fronts = event.get('data', {}).get('front_area', []) backs = event.get('data', {}).get('back_area', []) print(f"接收模块3数据 - 前区: {fronts} 后区: {backs}") self._store_module3_data(fronts, backs) def _process_module4_data(self, event: dict): """处理模块4数据""" analysis_data = event.get('analysis_result', {}) print("接收模块4趋势分析数据:") print(json.dumps(analysis_data, indent=2)) self._store_module4_data(analysis_data) def _store_module3_data(self, fronts, backs): """存储模块3数据""" with open(self.storage_path, 'a') as f: record = { 'timestamp': time.time(), 'type': 'module3', 'data': { 'fronts': fronts, 'backs': backs } } f.write(json.dumps(record) + '\n') def _store_module4_data(self, analysis_data): """存储模块4数据""" with open(self.storage_path, 'a') as f: record = { 'timestamp': time.time(), 'type': 'module4', 'data': analysis_data } f.write(json.dumps(record) + '\n') # ==================== 模块协调器 ==================== class EnhancedLotteryCoordinator(LotteryCoordinator): """增强版协调器(支持完整模块注册)""" def __init__(self): super().__init__() self._init_module_handlers() def _init_module_handlers(self): """初始化模块专用处理器""" # 模块3事件处理器 self.modules['module3'].handler = threading.Thread( target=self._handle_module3_events, daemon=True ) self.modules['module3'].handler.start() # 模块4事件处理器 self.modules['module4'].handler = threading.Thread( target=self._handle_module4_events, daemon=True ) self.modules['module4'].handler.start() def _handle_module3_events(self): """处理模块3事件流""" bus = EnhancedEventBus() while True: try: event = bus.channels['module_channel'].get(timeout=1) if event.get('module') == '模块3': print("处理模块3事件:", event) self.pool._process_module3_data(event) except queue.Empty: continue def _handle_module4_events(self): """处理模块4事件流""" bus = EnhancedEventBus() while True: try: event = bus.channels['module_channel'].get(timeout=1) if event.get('module') == '模块4': print("处理模块4事件:", event) self.pool._process_module4_data(event) except queue.Empty: continue # ==================== 模块实现 ==================== class Module3(AnalysisModule): """增强版模块3实现""" def submit_following_analysis(self, analysis_data: dict): """提交跟随分析结果""" super().submit({ 'type': 'following_analysis', 'data': analysis_data }) class Module4(Module4): """增强版模块4实现""" def submit_trend_analysis(self, analysis_data: dict): """提交趋势分析结果""" super().submit_analysis({ 'type': 'trend_analysis', 'data': analysis_data }) # ==================== 使用示例 ==================== if __name__ == "__main__": # 初始化协调器 coordinator = EnhancedLotteryCoordinator() # 模拟模块3数据 coordinator.submit('module3', { 'front_area': [5, 12, 23], 'back_area': [3, 8] }) # 模拟模块4数据 coordinator.submit('module4', { 'trend_analysis': { 'sum': 85, 'prime_ratio': '2:3', 'odd_even': '3:2' } }) # 等待处理完成 time.sleep(2) print("\n当前存储数据:") with open("lottery_data.json") as f: print(f.read())
05-27
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值