【linux内核】workqueue_struct工作队列
配置笔记本电脑安装centos7关闭盖子不休眠
struct workqueue_struct *my_wq;
my_wq = alloc_workqueue("my_wq", WQ_UNBOUND | WQ_MEM_RECLAIM, 1);
INIT_WORK(&my_work, my_work_func);
queue_work(my_wq, &my_work);
- 调用 alloc_workqueue():仅创建队列对象;
- 调用 queue_work():发现没有 worker,创建一个;
- 线程启动,执行 my_work_func();
- 执行完后线程保持空闲,等待下一个任务。
在/etc/systemd/logind.conf文件中添加一行配置:
HandleLidSwitch=ignore
一个 struct work_struct 在任意时刻,只能处于:未排队 / 正在执行 / 已排队 之一。同一个 work_struct, 如果已经在队列里或正在执行,再 queue_work(),返回 false,不会再次入队,但这条规则只针对“同一个 work_struct 实例”。
场景分析:一个结构体里定义了 两个 struct work_struct,分别执行不同的函数,投递到 同一个 workqueue_struct:
struct foo {
struct work_struct work_a;
struct work_struct work_b;
};
✅ 情况 A:work_a 在队列中,work_b 入队。是完全没问题的。work_a 和 work_b 是两个独立的 work。即使:work_a 还在队列里 / 正在跑。work_b 也可以成功 queue_work()。最终行为:按 workqueue 的调度顺序执行,串行 or 并行取决于你用的 queue 类型,不会导致第二个执行不了。
情况 B:重复 queue 同一个 work(容易踩坑):
queue_work(wq, &foo->work_a);
queue_work(wq, &foo->work_a); // ❌
第二次queue_work() 返回 false,不会再次执行但:不会取消第一次只是“合并请求”这点经常被误判成 “work 丢了”
两个 work 共用了同一个 work_struct:
struct foo {
struct work_struct work;
};
然后想复用:
INIT_WORK(&foo->work, fn_a);
queue_work(wq, &foo->work);
INIT_WORK(&foo->work, fn_b); // 💥 危险
queue_work(wq, &foo->work);
这是未定义行为,非常容易:第二个根本不执行,甚至直接炸。
推荐的设计模式:
两个不同逻辑 → 两个 work_struct(推荐)
struct foo {
struct work_struct worka;
struct work_struct workb;
};
INIT_WORK(&foo->worka, fn_a);
INIT_WORK(&foo->workb, fn_b);
queue_work(wq, &foo->worka);
queue_work(wq, &foo->workb);

浙公网安备 33010602011771号