一,使用work_struct , 和 INIT_WORK,schedule_work,组合。
#include <linux/init.h>
#include <linux/module.h>
#include <linux/time.h>
#include <linux/jiffies.h>
#include <linux/workqueue.h>
#include <linux/slab.h> //kmalloc kfree
#include <linux/sched.h>
#include <linux/delay.h>
static char data[] = "TTT work thread";
struct work_ctx{
struct work_struct A_work;
struct work_struct B_work;
char *str;
int arg;
}work_ctx;
struct work_ctx *my_work;
static void my_work_func_A(struct work_struct *work){
struct work_ctx *temp_work = container_of(work,struct work_ctx,A_work);
printk(KERN_INFO "[work]=> PID: A %d; NAME: %s\n", current->pid, current->comm);
printk(KERN_INFO "[work]=> sleep A 1 seconds\n");
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1 * HZ); //Wait 1 seconds
printk(KERN_INFO "[work]=> data A is: %d %s\n", temp_work->arg, temp_work->str);
}
static void my_work_func_B(struct work_struct *work){
struct work_ctx *temp_work = container_of(work,struct work_ctx,B_work);
printk(KERN_INFO "[work]=> PID: B %d; NAME: %s\n", current->pid, current->comm);
printk(KERN_INFO "[work]=> sleep B 1 seconds\n");
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1 * HZ); //Wait 1 seconds
printk(KERN_INFO "[work]=> data B is: %d %s\n", temp_work->arg, temp_work->str);
}
static int __init my_thread_init(void){
int count = 3;
my_work = kmalloc(sizeof(*my_work),GFP_KERNEL);
INIT_WORK(&my_work->A_work, my_work_func_A);
INIT_WORK(&my_work->B_work, my_work_func_B);
my_work->str = data;
while(count--){
msleep(5000);
my_work->arg = count;
schedule_work(&my_work->A_work);
schedule_work(&my_work->B_work);
}
return 0;
}
module_init(my_thread_init);
static void __exit my_thread_exit(void){
flush_work(&my_work->A_work);
flush_work(&my_work->B_work);
kfree(my_work);
}
module_exit(my_thread_exit);
MODULE_LICENSE("GPL");
运行结果:
[17336.005380] [work]=> PID: A 15522; NAME: kworker/0:1
[17336.005381] [work]=> sleep A 1 seconds
[17336.005384] [work]=> PID: B 14436; NAME: kworker/0:2
[17336.005384] [work]=> sleep B 1 seconds
[17337.030067] [work]=> data B is: 2 TTT work thread
[17337.030072] [work]=> data A is: 2 TTT work thread
[17341.125501] [work]=> PID: A 15472; NAME: kworker/0:3
[17341.125502] [work]=> sleep A 1 seconds
[17341.125505] [work]=> PID: B 15522; NAME: kworker/0:1
[17341.125505] [work]=> sleep B 1 seconds
[17342.149587] [work]=> data B is: 1 TTT work thread
[17342.149595] [work]=> data A is: 1 TTT work thread
[17346.245971] [work]=> PID: A 14436; NAME: kworker/0:2
[17346.245971] [work]=> sleep A 1 seconds
[17346.247788] [work]=> PID: B 15472; NAME: kworker/0:3
[17346.247788] [work]=> sleep B 1 seconds
[17347.270131] [work]=> data B is: 0 TTT work thread
[17347.270136] [work]=> data A is: 0 TTT work thread
可以看到 workthread,并不是同步的。这个方式可以通过加锁mutex_lock,时序问题。
我们也可以同workqueue_struct, INIT_WORK,queue_work 去解决,时序问题。
参考: