閘北網(wǎng)站建設(shè)公司dede打包好的網(wǎng)站怎么提取模板
鶴壁市浩天電氣有限公司
2026/01/22 08:19:22
閘北網(wǎng)站建設(shè)公司,dede打包好的網(wǎng)站怎么提取模板,賽雷猴是什么意思,wordpress 主題使用教程tasklet
tasklet機(jī)制是內(nèi)核定義的幾種softirq之一(常用)
根據(jù)優(yōu)先級不同內(nèi)核將tasklet分成兩種#xff1a;TASKLET_SOFTIRQ 和 HI_SOFTIRQ (后者優(yōu)先級高)
執(zhí)行時機(jī)通常是上半部分返回的時候。
1.1 tasklet機(jī)制初始化
在linux系統(tǒng)內(nèi)核初始化的時候#xff0c;通過調(diào)用softirq…tasklettasklet機(jī)制是內(nèi)核定義的幾種softirq之一(常用)根據(jù)優(yōu)先級不同內(nèi)核將tasklet分成兩種TASKLET_SOFTIRQ 和 HI_SOFTIRQ (后者優(yōu)先級高)執(zhí)行時機(jī)通常是上半部分返回的時候。1.1 tasklet機(jī)制初始化在linux系統(tǒng)內(nèi)核初始化的時候通過調(diào)用softirq_init( )為TASKLET_SOFTIRQ 和 HI_SOFTIRQ安裝了執(zhí)行函數(shù)。1.2 相關(guān)的操作struct tasklet_struct{struct tasklet_struct *next; //用來將系統(tǒng)中tasklet鏈接成鏈表unsigned long state; //記錄在系統(tǒng)中tasklet的狀態(tài)atomic_t count; //如果為0則不可被調(diào)度執(zhí)行void (*func)(unsigned long); //在tasklet上執(zhí)行函數(shù)或者延遲函數(shù)unsigned long data; //將data傳遞給fun指向的函數(shù)};1.2.1 初始化tasklet聲明并初始化一個靜態(tài)的tasklet對象//struct tasklet_struct name;//void func(unsigned long);//unsingned long data;DECLARE_TASKLET(name, func, data);動態(tài)初始化tasklet對象void tasklet_init(struct tasklet_struct *t, void (*func)(unsigned long), unsigned long data)–tasklet_init(name, fun, data);1.2.2 提交一個tasklet在聲明和初始化一個tasklet對象之后驅(qū)動程序需要調(diào)用tasklet_schedule來向系統(tǒng)提交tasklet(一般在中斷處理程序中提交)void tasklet_schedule(struct tasklet_struct *t)tasklet_schedule(name);工作隊(duì)列使用內(nèi)核自己帶的工作隊(duì)列工作隊(duì)列執(zhí)行的上下文是內(nèi)核線程因此可以調(diào)度和睡眠在Workqueue機(jī)制中Linux系統(tǒng)在初始化的時候通過init_workqueues(void)函數(shù)創(chuàng)建了一個workqueue隊(duì)列——events用戶可以直接初始化一個work_struct對象然后在該隊(duì)列中進(jìn)行調(diào)度使用更加方便。//定義一個工作節(jié)點(diǎn)structwork_sturctmy_wrok;//定一個處理函數(shù)voidmy_wq_func(structwork_struct*work);/*初始化工作節(jié)點(diǎn)并和處理函數(shù)綁定*/INIT_WORK(my_work,my_wq_func)/*使用內(nèi)核自己創(chuàng)建的工作隊(duì)列-events和處理線程, 提交工作節(jié)點(diǎn)(一般在中斷處理函數(shù)中)*/schedule_work(my_wq)---queue_work(system_wq,work);使用自己創(chuàng)建工作隊(duì)列首先創(chuàng)建工作隊(duì)列#define create_workqueue(name)alloc_workqueue((name), WQ_MEM_RECLAIM, 1)—struct workqueue_struct* myworkqueue create_workqueue(“mywq”); /創(chuàng)建工作隊(duì)列和處理線程/提交工作int queue_work(struct workqueue_struct *wq, struct work_struct *work)–queue_work(myworkqueue, my_work);#definecreate_workqueue(name)alloc_workqueue(%s,__WQ_LEGACY|WQ_MEM_RECLAIM,1,(name))structworkqueue_struct*alloc_workqueue(constchar*fmt,unsignedintflags,intmax_active,...){size_ttbl_size0;va_list args;structworkqueue_struct*wq;structpool_workqueue*pwq;/* * Unbound max_active 1 used to imply ordered, which is no * longer the case on NUMA machines due to per-node pools. While * alloc_ordered_workqueue() is the right way to create an ordered * workqueue, keep the previous behavior to avoid subtle breakages * on NUMA. */if((flagsWQ_UNBOUND)max_active1)flags|__WQ_ORDERED;/* see the comment above the definition of WQ_POWER_EFFICIENT */if((flagsWQ_POWER_EFFICIENT)wq_power_efficient)flags|WQ_UNBOUND;/* allocate wq and format name */if(flagsWQ_UNBOUND)tbl_sizenr_node_ids*sizeof(wq-numa_pwq_tbl[0]);wqkzalloc(sizeof(*wq)tbl_size,GFP_KERNEL);if(!wq)returnNULL;if(flagsWQ_UNBOUND){wq-unbound_attrsalloc_workqueue_attrs();if(!wq-unbound_attrs)gotoerr_free_wq;}va_start(args,max_active);vsnprintf(wq-name,sizeof(wq-name),fmt,args);va_end(args);max_activemax_active?:WQ_DFL_ACTIVE;max_activewq_clamp_max_active(max_active,flags,wq-name);/* init wq */wq-flagsflags;wq-saved_max_activemax_active;mutex_init(wq-mutex);atomic_set(wq-nr_pwqs_to_flush,0);INIT_LIST_HEAD(wq-pwqs);INIT_LIST_HEAD(wq-flusher_queue);INIT_LIST_HEAD(wq-flusher_overflow);INIT_LIST_HEAD(wq-maydays);wq_init_lockdep(wq);INIT_LIST_HEAD(wq-list);if(alloc_and_link_pwqs(wq)0)gotoerr_unreg_lockdep;if(wq_onlineinit_rescuer(wq)0)gotoerr_destroy;if((wq-flagsWQ_SYSFS)workqueue_sysfs_register(wq))gotoerr_destroy;/* * wq_pool_mutex protects global freeze state and workqueues list. * Grab it, adjust max_active and add the new wq to workqueues * list. */mutex_lock(wq_pool_mutex);mutex_lock(wq-mutex);for_each_pwq(pwq,wq)pwq_adjust_max_active(pwq);mutex_unlock(wq-mutex);list_add_tail_rcu(wq-list,workqueues);mutex_unlock(wq_pool_mutex);returnwq;err_unreg_lockdep:wq_unregister_lockdep(wq);wq_free_lockdep(wq);err_free_wq:free_workqueue_attrs(wq-unbound_attrs);kfree(wq);returnNULL;err_destroy:destroy_workqueue(wq);returnNULL;}EXPORT_SYMBOL_GPL(alloc_workqueue);queue_work/* not bound to any CPU, prefer the local CPU */,//WORK_CPU_UNBOUND NR_CPUS,staticinlineboolqueue_work(structworkqueue_struct*wq,structwork_struct*work){returnqueue_work_on(WORK_CPU_UNBOUND,wq,work);}