青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

posts - 297,  comments - 15,  trackbacks - 0
Linux Kernel Threads in Device Drivers 
Purpose 
This examples shows how to create and stop a kernel thread. 
The driver is implemented as a loadable module. In the init_module() routine five kernel threads are created. This kernel threads sleep one second, wake up, print a message and fall asleep again. On unload of the module (cleanup_module), the kernel threads are killed. 
The example has been tested with Linux kernel 2.4.2 on Intel (uni processor only) and Alpha platform (COMPAQ Personal Workstation 500au (uni processor), DS20 and ES40 (SMP). 
A version for the 2.2 kernel can be found here. Note: depending on the context of the creator of the threads the new threads may inherit properties from the parent you do not want to have. The new version avoids this by having keventd create the threads. The 2.2. kernel do not have a keventd, so this approach is not implementable there. 

Functions in example 
start_kthread: creates a new kernel thread. Can be called from any process context but not from interrupt. The functions blocks until the thread started. 
stop_kthread: stop the thread. Can be called from any process context but the thread to be terminated. Cannot be called from interrupt context. The function blocks until the thread terminated. 
init_kthread: sets the environment of the new threads. Is to be called out of the created thread. 
exit_kthread: needs to be called by the thread to be terminated on exit 
Creation of new Thread 
A new thread is created with kernel_thread(). The thread inherits properties from its parents. To make sure that we do not get any weired properties, we let keventd create the new thread. 
The new thread is created with start_kthread(). It uses a semaphore to block until the new thread is running. A down() blocks the start_kthread() routine until the corresponding up() call in init_kthread() is executed. 
The new thread must call init_kthread() in order to let the creator continue. 
Stop of new Thread 
stop_kthread() sets a flag that the thread uses to determine whether do die or not and sends a SIGKILL to the thread. This signal causes the thread to be woken up. On wakeup it will check for the flag and then terminate itself by calling exit_kthread and returning from the thread function. With a semaphore the stop_kthread() function blocks until the thread terminated. 
Initialization of new Thread 
Within the new created thread, init_kthread() needs to be called. This function sets a signal mask, initialises a wait queue, the termination flag and sets a new name for the thread. With a up() call it notifies the creator that the setup is done. 
Exit of new Thread 
When the thread receives the notification to terminate itself, is calls the exit_kthread() function. It notifies the stop_kthread() function that it terminated with an up() call. 
The new Thread itself 
The new thread is implemented in the example_thread() function. It runs an endless loop (for(;;)). In the loop it falls asleep with the interruptible_sleep_on_timeout() function. It comes out of this function either when the timeout expires or when a signal got caught. 
The "work" in the thread is to print out a message with printk. 
Kernel Versions 
The example has been tested on 2.4.2. 
Example Device Driver Code 
The example consists of four files: kthread.h, kthread.c, thread_drv.c and a Makefile 
kthread.h 
#ifndef _KTHREAD_H 
#define _KTHREAD_H 
#include <linux/config.h> 
#include <linux/version.h> 

#include <linux/kernel.h> 
#include <linux/sched.h> 
#include <linux/tqueue.h> 
#include <linux/wait.h> 

#include <asm/unistd.h> 
#include <asm/semaphore.h> 

/* a structure to store all information we need 
for our thread */ 
typedef struct kthread_struct 
{ 
/* private data */ 

/* Linux task structure of thread */ 
struct task_struct *thread; 
/* Task queue need to launch thread */ 
struct tq_struct tq; 
/* function to be started as thread */ 
void (*function) (struct kthread_struct *kthread); 
/* semaphore needed on start and creation of thread. */ 
struct semaphore startstop_sem; 

/* public data */ 

/* queue thread is waiting on. Gets initialized by 
init_kthread, can be used by thread itself. 
*/ 
wait_queue_head_t queue; 
/* flag to tell thread whether to die or not. 
When the thread receives a signal, it must check 
the value of terminate and call exit_kthread and terminate 
if set. 
*/ 
int terminate; 
/* additional data to pass to kernel thread */ 
void *arg; 
} kthread_t; 

/* prototypes */ 

/* start new kthread (called by creator) */ 
void start_kthread(void (*func)(kthread_t *), kthread_t *kthread); 

/* stop a running thread (called by "killer") */ 
void stop_kthread(kthread_t *kthread); 

/* setup thread environment (called by new thread) */ 
void init_kthread(kthread_t *kthread, char *name); 

/* cleanup thread environment (called by thread upon receiving termination signal) */ 
void exit_kthread(kthread_t *kthread); 

#endif 

kthread.c 
#include <linux/config.h> 
#include <linux/version.h> 

#if defined(MODVERSIONS) 
#include <linux/modversions.h> 
#endif 
#include <linux/kernel.h> 
#include <linux/sched.h> 
#include <linux/tqueue.h> 
#include <linux/wait.h> 
#include <linux/signal.h> 

#include <asm/semaphore.h> 
#include <asm/smplock.h> 

#include "kthread.h" 

/* private functions */ 
static void kthread_launcher(void *data) 
{ 
kthread_t *kthread = data; 
kernel_thread((int (*)(void *))kthread->function, (void *)kthread, 0); 

} 

/* public functions */ 

/* create a new kernel thread. Called by the creator. */ 
void start_kthread(void (*func)(kthread_t *), kthread_t *kthread) 
{ 
/* initialize the semaphore: 
we start with the semaphore locked. The new kernel 
thread will setup its stuff and unlock it. This 
control flow (the one that creates the thread) blocks 
in the down operation below until the thread has reached 
the up() operation. 
*/ 
init_MUTEX_LOCKED(&kthread->startstop_sem); 

/* store the function to be executed in the data passed to 
the launcher */ 
kthread->function=func; 

/* create the new thread my running a task through keventd */ 

/* initialize the task queue structure */ 
kthread->tq.sync = 0; 
INIT_LIST_HEAD(&kthread->tq.list); 
kthread->tq.routine = kthread_launcher; 
kthread->tq.data = kthread; 

/* and schedule it for execution */ 
schedule_task(&kthread->tq); 

/* wait till it has reached the setup_thread routine */ 
down(&kthread->startstop_sem); 

} 

/* stop a kernel thread. Called by the removing instance */ 
void stop_kthread(kthread_t *kthread) 
{ 
if (kthread->thread == NULL) 
{ 
printk("stop_kthread: killing non existing thread!\n"); 
return; 
} 

/* this function needs to be protected with the big 
kernel lock (lock_kernel()). The lock must be 
grabbed before changing the terminate 
flag and released after the down() call. */ 
lock_kernel(); 

/* initialize the semaphore. We lock it here, the 
leave_thread call of the thread to be terminated 
will unlock it. As soon as we see the semaphore 
unlocked, we know that the thread has exited. 
*/ 
init_MUTEX_LOCKED(&kthread->startstop_sem); 

/* We need to do a memory barrier here to be sure that 
the flags are visible on all CPUs. 
*/ 
mb(); 

/* set flag to request thread termination */ 
kthread->terminate = 1; 

/* We need to do a memory barrier here to be sure that 
the flags are visible on all CPUs. 
*/ 
mb(); 
kill_proc(kthread->thread->pid, SIGKILL, 1); 

/* block till thread terminated */ 
down(&kthread->startstop_sem); 

/* release the big kernel lock */ 
unlock_kernel(); 

/* now we are sure the thread is in zombie state. We 
notify keventd to clean the process up. 
*/ 
kill_proc(2, SIGCHLD, 1); 

} 

/* initialize new created thread. Called by the new thread. */ 
void init_kthread(kthread_t *kthread, char *name) 
{ 
/* lock the kernel. A new kernel thread starts without 
the big kernel lock, regardless of the lock state 
of the creator (the lock level is *not* inheritated) 
*/ 
lock_kernel(); 

/* fill in thread structure */ 
kthread->thread = current; 

/* set signal mask to what we want to respond */ 
siginitsetinv(&current->blocked, sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGTERM)); 

/* initialise wait queue */ 
init_waitqueue_head(&kthread->queue); 

/* initialise termination flag */ 
kthread->terminate = 0; 

/* set name of this process (max 15 chars + 0 !) */ 
sprintf(current->comm, name); 

/* let others run */ 
unlock_kernel(); 

/* tell the creator that we are ready and let him continue */ 
up(&kthread->startstop_sem); 

} 

/* cleanup of thread. Called by the exiting thread. */ 
void exit_kthread(kthread_t *kthread) 
{ 
/* we are terminating */ 

/* lock the kernel, the exit will unlock it */ 
lock_kernel(); 
kthread->thread = NULL; 
mb(); 

/* notify the stop_kthread() routine that we are terminating. */ 
up(&kthread->startstop_sem); 
/* the kernel_thread that called clone() does a do_exit here. */ 

/* there is no race here between execution of the "killer" and real termination 
of the thread (race window between up and do_exit), since both the 
thread and the "killer" function are running with the kernel lock held. 
The kernel lock will be freed after the thread exited, so the code 
is really not executed anymore as soon as the unload functions gets 
the kernel lock back. 
The init process may not have made the cleanup of the process here, 
but the cleanup can be done safely with the module unloaded. 
*/ 

} 

thread_drv.c 
#include <linux/config.h> 
#include <linux/version.h> 

#include <linux/module.h> 
#if defined(MODVERSIONS) 
#include <linux/modversions.h> 
#endif 

#include <linux/kernel.h> 
#include <linux/string.h> 
#include <linux/errno.h> 
#include <linux/sched.h> 

#include "kthread.h" 

#define NTHREADS 5 

/* the variable that contains the thread data */ 
kthread_t example[NTHREADS]; 

/* prototype for the example thread */ 
static void example_thread(kthread_t *kthread); 

/* load the module */ 
int init_module(void) 
{ 
int i; 

/* create new kernel threads */ 
for (i=0; i <NTHREADS; i++) 
start_kthread(example_thread, &example); 

return(0); 
} 

/* remove the module */ 
void cleanup_module(void) 
{ 
int i; 

/* terminate the kernel threads */ 
for (i=0; i<NTHREADS; i++) 
stop_kthread(&example); 

return; 
} 

/* this is the thread function that we are executing */ 
static void example_thread(kthread_t *kthread) 
{ 
/* setup the thread environment */ 
init_kthread(kthread, "example thread"); 

printk("hi, here is the kernel thread\n"); 

/* an endless loop in which we are doing our work */ 
for(;;) 
{ 
/* fall asleep for one second */ 
interruptible_sleep_on_timeout(&kthread->queue, HZ); 

/* We need to do a memory barrier here to be sure that 
the flags are visible on all CPUs. 
*/ 
mb(); 

/* here we are back from sleep, either due to the timeout 
(one second), or because we caught a signal. 
*/ 
if (kthread->terminate) 
{ 
/* we received a request to terminate ourself */ 
break; 
} 

/* this is normal work to do */ 
printk("example thread: thread woke up\n"); 
} 
/* here we go only in case of termination of the thread */ 

/* cleanup the thread, leave */ 
exit_kthread(kthread); 

/* returning from the thread here calls the exit functions */ 
} 

Makefile 
# set to your kernel tree 
KERNEL = /usr/src/linux 

# get the Linux architecture. Needed to find proper include file for CFLAGS 
ARCH=$(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
# set default flags to compile module 
CFLAGS = -D__KERNEL__ -DMODULE -I$(KERNEL)/include 
CFLAGS+= -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strict-aliasing 

all: thread_mod.o 

# get configuration of kernel 
include $(KERNEL)/.config 
# modify CFLAGS with architecture specific flags 
include $(KERNEL)/arch/${ARCH}/Makefile 

# enable the module versions, if configured in kernel source tree 
ifdef CONFIG_MODVERSIONS 
CFLAGS+= -DMODVERSIONS -include $(KERNEL)/include/linux/modversions.h 
endif 
# enable SMP, if configured in kernel source tree 
ifdef CONFIG_SMP 
CFLAGS+= -D__SMP__ 
endif 

# note: we are compiling the driver object file and then linking 
# we link it into the module. With just one object file as in 
# this example this is not needed. We can just load the object 
# file produced by gcc 
# link the thread driver module 
thread_mod.o: thread_drv.o kthread.o 
ld -r -o thread_mod.o thread_drv.o kthread.o 
# compile the kthread object file 
kthread.o: kthread.c kthread.h 
gcc $(CFLAGS) -c kthread.c 
# compile the thread driver 
thread_drv.o: thread_drv.c kthread.h 
gcc $(CFLAGS) -c thread_drv.c 

clean: 
rm -f *.o 

Bugs 
The code assumes that keventd is running with PID 2. 
Comments, Corrections 
Please send comments, corrections etc. to the address below.

from:
http://www.linuxforum.net/forum/showflat.php?Cat=&Board=linuxK&Number=282973&page=15&view=collapsed&sb=5&o=all


posted on 2011-03-22 21:08 chatler 閱讀(706) 評論(0)  編輯 收藏 引用 所屬分類: linux kernel
<2011年3月>
272812345
6789101112
13141516171819
20212223242526
272829303112
3456789

常用鏈接

留言簿(10)

隨筆分類(307)

隨筆檔案(297)

algorithm

Books_Free_Online

C++

database

Linux

Linux shell

linux socket

misce

  • cloudward
  • 感覺這個博客還是不錯,雖然做的東西和我不大相關(guān),覺得看看還是有好處的

network

OSS

  • Google Android
  • Android is a software stack for mobile devices that includes an operating system, middleware and key applications. This early look at the Android SDK provides the tools and APIs necessary to begin developing applications on the Android platform using the Java programming language.
  • os161 file list

overall

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久久亚洲影院你懂的| 在线观看日产精品| 一区二区三区高清不卡| 亚洲日本中文字幕| 欧美色精品天天在线观看视频| 在线亚洲精品| 欧美一级网站| 国产午夜一区二区三区| 免费在线欧美黄色| 欧美日韩国产123| 亚洲影音先锋| 欧美在线观看视频在线| 亚洲国产裸拍裸体视频在线观看乱了中文 | 亚洲欧洲一区二区三区久久| 欧美视频一区二区三区…| 欧美一级在线亚洲天堂| 久久国产日韩欧美| 一本一本久久a久久精品综合麻豆| 99成人精品| 在线电影国产精品| 一区二区电影免费在线观看| 国内偷自视频区视频综合| 亚洲国产高潮在线观看| 国产精品尤物| 亚洲人成免费| 亚洲成人中文| 亚洲一区二区免费在线| 亚洲国产精品va在线看黑人动漫| 日韩午夜电影| 亚洲全部视频| 久久久久久亚洲精品不卡4k岛国| 99视频在线观看一区三区| 欧美在线观看你懂的| 一区二区三区 在线观看视| 久久蜜桃资源一区二区老牛| 午夜精品视频| 欧美日韩国产成人在线| 欧美成人影音| 国产偷自视频区视频一区二区| 亚洲日本va在线观看| 在线观看日韩www视频免费| 亚洲免费视频成人| 亚洲视频图片小说| 免费试看一区| 免费一区二区三区| 国产精品视频区| 一本色道久久综合亚洲精品按摩| 亚洲国产精品小视频| 久久久高清一区二区三区| 欧美一级艳片视频免费观看| 欧美日韩一区二区三区在线看| 欧美福利视频一区| 一色屋精品视频免费看| 欧美一级在线亚洲天堂| 欧美三级韩国三级日本三斤| 在线观看成人网| 久久精品国语| 久久久久免费视频| 国产综合精品| 欧美一区二区三区视频免费播放| 午夜一区不卡| 国产日韩欧美一区二区三区在线观看 | 亚洲国产精品一区二区三区| 在线欧美三区| 久热精品视频在线观看一区| 久久婷婷蜜乳一本欲蜜臀| 国产一区视频网站| 久久国产欧美日韩精品| 理论片一区二区在线| 在线看日韩av| 欧美了一区在线观看| 亚洲另类在线视频| 亚洲自拍16p| 国产色综合久久| 久久久一本精品99久久精品66| 另类激情亚洲| 日韩视频在线免费| 欧美日韩一二三四五区| 亚洲午夜视频在线观看| 久久久国产精品一区| 亚洲电影成人| 欧美久久综合| 亚洲在线观看免费视频| 久久久噜噜噜久噜久久| 亚洲精品乱码久久久久久蜜桃91| 欧美精品三区| 欧美一区二区精美| 欧美激情中文字幕在线| 一区二区免费在线观看| 国产欧美在线观看| 久久综合99re88久久爱| 亚洲精品国产精品国自产在线| 亚洲永久精品国产| 激情另类综合| 欧美亚洲成人精品| 久久在线播放| 中文av一区特黄| 免费成人你懂的| 亚洲一区二区三区精品视频| 国产一区二区精品久久99| 欧美欧美午夜aⅴ在线观看| 午夜免费在线观看精品视频| 亚洲电影观看| 久久久久免费| 亚洲综合精品自拍| 亚洲人体一区| 激情久久影院| 国产精品热久久久久夜色精品三区 | 小嫩嫩精品导航| 亚洲美洲欧洲综合国产一区| 国产精品一区视频| 欧美日韩成人在线| 久久天天躁狠狠躁夜夜爽蜜月| 亚洲天堂成人| 亚洲毛片在线| 亚洲风情亚aⅴ在线发布| 欧美一区二区成人6969| 在线一区二区日韩| 亚洲美女黄色| 亚洲第一黄网| 伊人天天综合| 欧美视频精品在线| 久久亚洲综合| 久久黄金**| 亚洲在线视频观看| 一区二区三区四区国产| 亚洲人成啪啪网站| 伊人久久大香线蕉综合热线 | 牛牛精品成人免费视频| 久久大逼视频| 欧美一区2区三区4区公司二百| 亚洲一区二区三区中文字幕| 夜夜爽www精品| 国产精品99久久久久久久女警| 91久久精品国产91久久性色| 欧美成人精品一区二区| 蜜乳av另类精品一区二区| 久久久精品一区| 久久久噜噜噜久久狠狠50岁| 久久久99爱| 久久伊人精品天天| 欧美成人a∨高清免费观看| 欧美va亚洲va国产综合| 欧美黄色影院| 亚洲国产一区二区三区青草影视| 亚洲高清二区| 亚洲美洲欧洲综合国产一区| 日韩视频在线一区二区三区| 亚洲无人区一区| 午夜精品理论片| 欧美在线视频一区二区三区| 久久久99精品免费观看不卡| 久久这里有精品15一区二区三区| 久久亚洲综合网| 欧美极品一区| 国产精品乱码一区二区三区| 国产欧美va欧美不卡在线| 国产午夜精品一区二区三区视频| 好吊色欧美一区二区三区四区| 亚洲国产精品va在线观看黑人| 亚洲美女精品一区| 午夜精品亚洲| 欧美/亚洲一区| 夜夜躁日日躁狠狠久久88av| 亚洲欧美日韩国产精品 | a4yy欧美一区二区三区| 亚洲摸下面视频| 久久综合九色九九| 欧美日韩国产成人在线免费| 国产视频欧美| 亚洲毛片在线观看.| 午夜久久tv| 亚洲成色精品| 亚洲欧美日韩国产一区二区三区| 久久成人免费网| 欧美精品一区二区久久婷婷| 国产九九精品| 亚洲日本在线视频观看| 香蕉久久夜色| 亚洲黄色在线视频| 亚洲欧美日韩视频二区| 欧美国产激情| 国产一区二区三区久久| 亚洲精品四区| 久久婷婷久久| 亚洲专区欧美专区| 欧美电影免费网站| 国产一区二区三区自拍| 99精品视频免费观看| 久热精品视频在线观看| 亚洲小说春色综合另类电影| 欧美黄色影院| 狠狠干狠狠久久| 亚洲欧美激情视频在线观看一区二区三区| 久久在线免费观看| 午夜久久福利| 国产精品亚洲精品| 亚洲午夜久久久久久久久电影网| 欧美3dxxxxhd| 久久综合福利|