Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2149237
  • 博文数量: 438
  • 博客积分: 3871
  • 博客等级: 中校
  • 技术积分: 6075
  • 用 户 组: 普通用户
  • 注册时间: 2011-09-10 00:11
个人简介

邮箱: wangcong02345@163.com

文章分类

全部博文(438)

文章存档

2017年(15)

2016年(119)

2015年(91)

2014年(62)

2013年(56)

2012年(79)

2011年(16)

分类: Android平台

2014-03-03 12:15:35

两个结构体
  1. struct work_struct {
  2.     atomic_long_t data;
  3.     struct list_head entry;
  4.     work_func_t func;
  5. };


  1. struct workqueue_struct {
  2.     unsigned int        flags;      
  3.     union {
  4.         struct cpu_workqueue_struct __percpu    *pcpu;
  5.         struct cpu_workqueue_struct        *single;
  6.         unsigned long                v;
  7.     } cpu_wq;              
  8.     struct list_head    list;       

  9.     struct mutex    flush_mutex;   
  10.     int             work_color;    
  11.     int             flush_color;    
  12.     atomic_t        nr_cwqs_to_flush;
  13.     struct wq_flusher   *first_flusher;   
  14.     struct list_head    flusher_queue;    
  15.     struct list_head    flusher_overflow;

  16.     mayday_mask_t       mayday_mask;   
  17.     struct worker       *rescuer;

  18.     int                 saved_max_active;
  19.     const char          *name;       
  20. };





工作队列的使用步骤如下:
  1. //0.首先定义两个结构体:
  2. struct work_struct my_work;
  3. struct workqueue_struct *my_work_queue;
  4. //1.填充一个work_struct
  5. INIT_WORK(&my_work, my_work_process);
  6. //2.显式的创建一个工作队列
  7. my_work_queue = create_workqueue("my_work");
  8. //3.将工作提交到工作队列
  9. queue_work(my_work_queue, &my_work);
  10. //4. 调用工作队列处理函数
  11. my_work_process(struct work_struct *work)

1. 填充一个work_struct
  1. #define INIT_WORK(_work, _func)                    \
  2.     do {                            \
  3.         __INIT_WORK((_work), (_func), 0);        \
  4.     } while (0)
即:
  1. #define __INIT_WORK(_work, _func, _onstack)                \
  2.     do {                                \
  3.         __init_work((_work), _onstack);                \
  4.         (_work)->data = (atomic_long_t) WORK_DATA_INIT();    \
  5.         INIT_LIST_HEAD(&(_work)->entry);            \
  6.         PREPARE_WORK((_work), (_func));                \
  7.     } while (0)
展开后:
  1. __init_work(my_work, 0);
  2. my_work->data = (atomic_long_t) WORK_DATA_INIT();
  3. INIT_LIST_HEAD(&my_work->entry);
  4. PREPARE_WORK(my_work, my_work_process);


2. 显式的创建一个工作队列
  1. #define create_workqueue(name)                    \
  2.     alloc_workqueue((name), WQ_MEM_RECLAIM, 1)
  3. #define create_freezable_workqueue(name)            \
  4.     alloc_workqueue((name), WQ_FREEZABLE | WQ_UNBOUND | WQ_MEM_RECLAIM, 1)
  5. #define create_singlethread_workqueue(name)            \
  6.     alloc_workqueue((name), WQ_UNBOUND | WQ_MEM_RECLAIM, 1)
create_workqueue 与  create_singlethread_workqueue都是调用了alloc_workqueue


  1. #define alloc_workqueue(name, flags, max_active)        \
  2.     __alloc_workqueue_key((name), (flags), (max_active), NULL, NULL)


  3. struct workqueue_struct *__alloc_workqueue_key(const char *name,unsigned int flags, int max_active,  struct lock_class_key *key, const char *lock_name)
  4. {
  5.     struct workqueue_struct *wq;
  6.     unsigned int cpu;

  7.     if (flags & WQ_MEM_RECLAIM)
  8.         flags |= WQ_RESCUER;
  9.     if (flags & WQ_UNBOUND)
  10.         flags |= WQ_HIGHPRI;

  11.     max_active = max_active ?: WQ_DFL_ACTIVE;
  12.     max_active = wq_clamp_max_active(max_active, flags, name);

  13.     wq = kzalloc(sizeof(*wq), GFP_KERNEL);

  14.     wq->flags = flags;
  15.     wq->saved_max_active = max_active;
  16.     mutex_init(&wq->flush_mutex);
  17.     atomic_set(&wq->nr_cwqs_to_flush, 0);
  18.     INIT_LIST_HEAD(&wq->flusher_queue);
  19.     INIT_LIST_HEAD(&wq->flusher_overflow);

  20.     wq->name = name;
  21.     lockdep_init_map(&wq->lockdep_map, lock_name, key, 0);
  22.     INIT_LIST_HEAD(&wq->list);

  23.     alloc_cwqs(wq);        

  24.     for_each_cwq_cpu(cpu, wq) {
  25.         struct cpu_workqueue_struct *cwq = get_cwq(cpu, wq);
  26.         struct global_cwq *gcwq = get_gcwq(cpu);

  27.         cwq->gcwq = gcwq;
  28.         cwq->wq = wq;
  29.         cwq->flush_color = -1;
  30.         cwq->max_active = max_active;
  31.         INIT_LIST_HEAD(&cwq->delayed_works);
  32.     }

  33.     if (flags & WQ_RESCUER) {
  34.         struct worker *rescuer;
  35.         alloc_mayday_mask(&wq->mayday_mask, GFP_KERNEL);
  36.         wq->rescuer = rescuer = alloc_worker();
  37.         rescuer->task = kthread_create(rescuer_thread, wq, "%s", name);
  38.         rescuer->task->flags |= PF_THREAD_BOUND;
  39.         wake_up_process(rescuer->task);
  40.     }

  41.     spin_lock(&workqueue_lock);

  42.     if (workqueue_freezing && wq->flags & WQ_FREEZABLE)
  43.         for_each_cwq_cpu(cpu, wq)
  44.             get_cwq(cpu, wq)->max_active = 0;

  45.     list_add(&wq->list, &workqueues);

  46.     spin_unlock(&workqueue_lock);

  47.     return wq;
  48. }
  49. EXPORT_SYMBOL_GPL(__alloc_workqueue_key);








阅读(1590) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~