Linux内核分析之工作队列

struct workqueue_struct *__create_workqueue_key(const char *name,                           int singlethread,                           int freezeable,                           int rt,                           struct lock_class_key *key,                           const char *lock_name)   {       struct workqueue_struct *wq;       struct cpu_workqueue_struct *cwq;       int err = 0, cpu;       /*分配wq结构*/       wq = kzalloc(sizeof(*wq), GFP_KERNEL);       if (!wq)           return NULL;       /*分配cwq结构*/       wq->cpu_wq = alloc_percpu(struct cpu_workqueue_struct);       if (!wq->cpu_wq) {           kfree(wq);           return NULL;       }          wq->name = name;       lockdep_init_map(&wq->lockdep_map, lock_name, key, 0);       wq->singlethread = singlethread;       wq->freezeable = freezeable;       wq->rt = rt;       INIT_LIST_HEAD(&wq->list);          if (singlethread) {/*如果设置了单线程,只创建一个*/           /*初始化cwq*/           cwq = init_cpu_workqueue(wq, singlethread_cpu);           /*创建内核线程*/           err = create_workqueue_thread(cwq, singlethread_cpu);           /*唤醒刚创建的内核线程*/           start_workqueue_thread(cwq, -1);       } else {/*反之,每个cpu创建一个线程*/           cpu_maps_update_begin();           /*           * We must place this wq on list even if the code below fails.           * cpu_down(cpu) can remove cpu from cpu_populated_map before           * destroy_workqueue() takes the lock, in that case we leak           * cwq[cpu]->thread.           */           spin_lock(&workqueue_lock);           list_add(&wq->list, &workqueues);           spin_unlock(&workqueue_lock);           /*           * We must initialize cwqs for each possible cpu even if we           * are going to call destroy_workqueue() finally. Otherwise           * cpu_up() can hit the uninitialized cwq once we drop the           * lock.           */           for_each_possible_cpu(cpu) {/*对每个cpu*/               cwq = init_cpu_workqueue(wq, cpu);               if (err || !cpu_online(cpu))                   continue;               err = create_workqueue_thread(cwq, cpu);               start_workqueue_thread(cwq, cpu);           }           cpu_maps_update_done();       }          if (err) {           destroy_workqueue(wq);           wq = NULL;       }       return wq;   }  

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/22952.html