如何在线程f1()、f2()激活运行前调用钩子函数g()?
线程唤醒时自动调用钩子函数的实现方案
要实现线程每次被唤醒运行前自动调用钩子函数g(),核心思路是对原线程函数进行包装——让线程的执行逻辑先触发g(),再执行原函数的业务代码。下面分两种常用语言给出具体实现:
Python 实现
利用装饰器封装线程函数,确保每次线程启动或从休眠/等待中唤醒后,先执行g():
import threading import time def g(): print(f"Hook g() triggered at {time.strftime('%H:%M:%S')}") def f1(): while True: print("Executing f1() logic") time.sleep(2) # 模拟线程休眠,让出CPU def f2(): while True: print("Executing f2() logic") time.sleep(3) # 通用钩子包装装饰器 def wrap_with_hook(func): def wrapped(): while True: g() # 线程激活时先调用钩子 func() return wrapped # 创建带钩子的线程 thread_f1 = threading.Thread(target=wrap_with_hook(f1)) thread_f2 = threading.Thread(target=wrap_with_hook(f2)) thread_f1.start() thread_f2.start()
说明
- 装饰器
wrap_with_hook将原线程函数包裹在循环中,每次线程从休眠中被调度唤醒后,都会先执行g()再进入原函数逻辑。 - 如果是一次性执行的线程(非循环),可去掉包装内的循环,直接写
g(); func();,确保线程启动前调用一次g()。 - 若线程因条件变量、锁等待被唤醒,可将
g()放在等待语句的紧后方,保证唤醒后立即触发钩子。
C++ 实现
通过模板包装函数实现线程逻辑的钩子注入:
#include <iostream> #include <thread> #include <chrono> #include <ctime> void g() { auto now = std::chrono::system_clock::now(); std::time_t curr_time = std::chrono::system_clock::to_time_t(now); std::cout << "Hook g() triggered at " << std::ctime(&curr_time); } void f1() { while (true) { std::cout << "Executing f1() logic\n"; std::this_thread::sleep_for(std::chrono::seconds(2)); } } void f2() { while (true) { std::cout << "Executing f2() logic\n"; std::this_thread::sleep_for(std::chrono::seconds(3)); } } // 通用钩子包装模板 template<typename Func> void hook_wrapper(Func func) { while (true) { g(); func(); } } int main() { std::thread t1(hook_wrapper<decltype(f1)>, f1); std::thread t2(hook_wrapper<decltype(f2)>, f2); t1.join(); t2.join(); return 0; }
说明
- 模板函数
hook_wrapper适配任意线程函数类型,确保线程每次被调度执行时先触发g()。 - 若需处理平台级别的线程切换钩子(比如捕获所有线程调度事件),可依赖系统API(如Windows的
SetWinEventHook、Linux的ptrace),但这种方式复杂度高且平台依赖,非特殊场景不推荐。
内容的提问来源于stack exchange,提问作者OhWizz3
相关产品推荐
相关产品推荐

