linux 工作队列
书上写的工作队列的实现是创建一个单独的线程来执行相应的work. 但是最新的内核实现却不是这样的,原先的工作队列的接口都快要废弃了, New API:alloc_workqueue(name, flags, max_active)alloc_ordered_workqueue(const char *name, unsigned int flags){
书上写的工作队列的实现是创建一个单独的线程来执行相应的work. 但是最新的内核实现却不是这样的,原先的工作队列的接口都快要废弃了,
New API:
alloc_workqueue(name, flags, max_active)
alloc_ordered_workqueue(const char *name, unsigned int flags)
{
return alloc_workqueue(name, WQ_UNBOUND | flags, 1);
}
当向一个工作队列提交一个工作时,它并不是在指定的线程里运行,系统会维护一个Worker Pool, 每个Worker跑在一个单独的线程里,每一个CPU都有一个Worker Pool. 当有work需要处理时,就唤醒一个Worker,这样就减少了系统资源的占用(原先的实现是每创建一个工作队列,系统就创建一个线程,由于每个线程都需要有task_struct, pid等资源, 这样当系统中工作队列一多的话,资源占用率就很高了). 由于内核空间是所有进程共享的一块地址空间,因此在不同进程向工作队列提交的工作时,用户其实不用关心我这个工作到底是在哪个进程中处理的,但是这样的话,如果两个工作需要同步的话(比如访问一个共享的资源时),就得仔细考虑了,两个工作向同一个工作队列提交时,可能会被同时执行(分别跑在不同的CPU上), 这样RACE就产生了, 为了解决这个问题, 引入了WQ_UNBOUND标志 和 max_acitve = 1, 这两个参数指明了向这个工作队列提交一个工作时,这个工作不会绑定在特定的CPU上(如果没有指明WQ_UNBOUND 标志的话,在哪个CPU上提交的工作一定会在那个CPU上执行), max_active指明了这个工作队列后台有多少个worker线程与之绑定,默认参数为0,让系统来指定后台线程数。
更多推荐
所有评论(0)