INIT_WORK和INIT_DELAYED_WORK
来源:互联网 发布:php编辑器代码 编辑:程序博客网 时间:2024/05/29 08:48
http://blog.csdn.net/bingqingsuimeng/article/details/7891157?readlog
这两个宏都定义于include/linux/workqueue.h中:
79 #define INIT_WORK(_work, _func) /
80 do { /
81 (_work)->data = (atomic_long_t) WORK_DATA_INIT(); /
82 INIT_LIST_HEAD(&(_work)->entry); /
83 PREPARE_WORK((_work), (_func)); /
84 } while (0)
85
86 #define INIT_DELAYED_WORK(_work, _func) /
87 do { /
88 INIT_WORK(&(_work)->work, (_func)); /
89 init_timer(&(_work)->timer); /
90 } while (0)
localhost:/usr/src/linux-2.6.22.1/drivers/usb/core # ps -el
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 0 1 0 0 76 0 - 195 - ? 00:00:02 init
1 S 0 2 1 0 -40 - - 0 migrat ? 00:00:00 migration/0
1 S 0 3 1 0 94 19 - 0 ksofti ? 00:00:00 ksoftirqd/0
1 S 0 4 1 0 -40 - - 0 migrat ? 00:00:00 migration/1
1 S 0 5 1 0 94 19 - 0 ksofti ? 00:00:00 ksoftirqd/1
1 S 0 6 1 0 -40 - - 0 migrat ? 00:00:00 migration/2
5 S 0 18 1 0 70 -5 - 0 worker ? 00:00:00 events/0
1 S 0 19 1 0 70 -5 - 0 worker ? 00:00:00 events/1
5 S 0 20 1 0 70 -5 - 0 worker ? 00:00:00 events/2
5 S 0 21 1 0 70 -5 - 0 worker ? 00:00:00 events/3
5 S 0 22 1 0 70 -5 - 0 worker ? 00:00:00 events/4
1 S 0 23 1 0 70 -5 - 0 worker ? 00:00:00 events/5
5 S 0 24 1 0 70 -5 - 0 worker ? 00:00:00 events/6
5 S 0 25 1 0 70 -5 - 0 worker ? 00:00:00 events/7
events/0到events/7,0啊7啊这些都是处理器的编号,每个处理器对应其中的一个线程.要是您的计算机只有一个处理器,那么您只能看到一个这样的线程,events/0,您要是双处理器那您就会看到多出一个events/1的线程
这些events被叫做工作者线程,或者说worker threads,更确切的说,这些应该是缺省的工作者线程.而与工作者线程相关的一个概念就是工作队列,或者叫work queue.工作队列的作用就是把工作推后,交由一个内核线程去执行,更直接的说就是如果您写了一个函数,而您现在不想马上执行它,您想在将来某个时刻去执行它,那您用工作队列准没错.您大概会想到中断也是这样,提供一个中断服务函数,在发生中断的时候去执行,没错,和中断相比,工作队列最大的好处就是可以调度可以睡眠,灵活性更好.
关于工作队列机制,咱们还会用到另外两个函数,它们是cancel_delayed_work(struct delayed_work *work)和flush_scheduled_work().其中cancel_delayed_work()的意思不言自明,对一个延迟执行的工作来说,这个函数的作用是在这个工作还未执行的时候就把它给取消掉.
而flush_scheduled_work()的作用,是为了防止有竞争条件的出现,您要是对竞争条件不是很明白,那也不要紧,反正基本上每次cancel_delayed_work之后您都得调用flush_scheduled_work()这个函数,特别是对于内核模块,如果一个模块使用了工作队列机制,并且利用了events这个缺省队列,那么在卸载这个模块之前,您必须得调用这个函数,这叫做刷新一个工作队列,也就是说,函数会一直等待,直到队列中所有对象都被执行以后才返回.当然,在等待的过程中,这个函数可以进入睡眠.反正刷新完了之后,这个函数会被唤醒,然后它就返回了.关于这里这个竞争,可以这样理解,events对应的这个队列,人家本来是按部就班的执行,一个一个来,您要是突然把您的模块给卸载了,或者说你把你的那个工作从工作队列里取出来了,那events作为队列管理者,它可能根本就不知道,比如说它先想好了,下午3点执行队列里的第N个成员,可是您突然把第N-1个成员给取走了,那您说这是不是得出错?所以,为了防止您这种唯恐天下不乱的人做出冒天下之大不韪的事情来,提供了一个函数,flush_scheduled_work(),给您调用,以消除所谓的竞争条件,其实说竞争太专业了点,说白了就是防止混乱吧.
- INIT_WORK和INIT_DELAYED_WORK详解
- INIT_WORK和INIT_DELAYED_WORK详解
- INIT_WORK和INIT_DELAYED_WORK详解
- INIT_WORK和INIT_DELAYED_WORK详解
- INIT_WORK和INIT_DELAYED_WORK详解
- INIT_WORK和INIT_DELAYED_WORK详解
- INIT_WORK和INIT_DELAYED_WORK详解
- INIT_WORK和INIT_DELAYED_WORK详解
- INIT_WORK和INIT_DELAYED_WORK详解
- INIT_WORK和INIT_DELAYED_WORK详解
- INIT_WORK和INIT_DELAYED_WORK
- INIT_DELAYED_WORK和INIT_WORK定时器中断函数
- INIT_WORK和container_of
- INIT_WORK
- INIT_DELAYED_WORK() 函数剖析
- INIT_DELAYED_WORK() 函数剖析
- INIT_DELAYED_WORK() 函数剖析
- INIT_DELAYED_WORK() 函数剖析
- Yocto: Building Yocto with meta-altera
- LeetCode--Unique Paths II
- 编写切面日志
- graphviz 路径问题
- redis3.0配置文件详解
- INIT_WORK和INIT_DELAYED_WORK
- Android-9种通话状态(精确)
- 如何生成关键词云图
- android中build.gradle详细说明
- Design Pattern 0: Intro
- 斯坦福大学机器学习笔记——多变量的线性回归以及梯度下降法注意事项(内有代码)
- 欢迎使用CSDN-markdown编辑器
- 应是绿肥红瘦
- js中把已知对象循环遍历出来再存入新的数组中