work thread 多线程问题(二)

一,使用work_struct, INIT_WORK,queue_work, workqueue_struct,create_singlethread_workqueue (create_workqueue) 组合。

      简单做一些解释:

     workqueue_struct                         ---- queue 数据结构

     queue_work                                   ----  启动的这个work。

     create_workqueue                         ----  用于创建一个workqueue队列,多核中,有个多个队列。为系统中的每个CPU都创建一个内核线程。

     create_singlethread_workqueue  ----  用于创建一个workqueue队列,为多核中,也只创建一个内核线程。

#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 queue work thread";

struct work_ctx{
	struct work_struct A_work;
	struct work_struct B_work;
	char *str;
	int arg;
}work_ctx;

static struct work_ctx *my_work;
static struct workqueue_struct* work_queue;

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 3 seconds\n");
	// set_current_state(TASK_INTERRUPTIBLE);
	msleep(3000); //Wait 3 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 3 seconds\n");
	// set_current_state(TASK_INTERRUPTIBLE);
	msleep(3000); //Wait 3 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;
	work_queue = create_singlethread_workqueue("TTT_work_thread");
	my_work = kmalloc(sizeof(*my_work),GFP_KERNEL);	
    if (work_queue != NULL) {
		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;
		if (work_queue != NULL) {
			queue_work(work_queue, &my_work->A_work);
			queue_work(work_queue, &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);

	destroy_workqueue(work_queue);
	kfree(my_work);
}

module_exit(my_thread_exit);

MODULE_LICENSE("GPL");	

运行结果:

[11432.420834] [work]=> PID: A 5530; NAME: kworker/u2:3
[11432.420835] [work]=> sleep A 3 seconds
[11435.492808] [work]=> data A is: 2  TTT queue work thread
[11435.492816] [work]=> PID: B 5530; NAME: kworker/u2:3
[11435.492817] [work]=> sleep B 3 seconds
[11438.564912] [work]=> data B is: 1  TTT queue work thread
[11438.564918] [work]=> PID: A 5530; NAME: kworker/u2:3
[11438.564919] [work]=> sleep A 3 seconds
[11441.636667] [work]=> data A is: 1  TTT queue work thread
[11441.636676] [work]=> PID: B 5530; NAME: kworker/u2:3
[11441.636677] [work]=> sleep B 3 seconds
[11444.709336] [work]=> data B is: 0  TTT queue work thread
[11444.709339] [work]=> PID: A 5530; NAME: kworker/u2:3
[11444.709339] [work]=> sleep A 3 seconds
[11447.780392] [work]=> data A is: 0  TTT queue work thread
[11447.780400] [work]=> PID: B 5530; NAME: kworker/u2:3
[11447.780400] [work]=> sleep B 3 seconds
[11450.852598] [work]=> data B is: 0  TTT queue work thread
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值