kthread 예

kthread_create: 라인을 만듭니다.
struct  task_struct  *kthread_create(int  (*threadfn)(void  *data),void  *data,const  char  *namefmt,  ...);
스레드가 생성된 후 바로 실행되지 않고 kthreadcreate()가 반환하는taskstruct 포인터가 wake 에 전달됨up_프로세스 (), 그리고 이 함수를 통해 라인을 실행합니다.
kthread_run: 스레드를 만들고 시작하는 함수:
struct  task_struct  *kthread_run(int  (*threadfn)(void  *data),void  *data,const  char  *namefmt,  ...);
kthread_stop: 신호를 보내서 라인을 종료합니다.
int  kthread_stop(struct  task_struct  *thread);
스레드가 시작되면 이 스레드가 주동적으로 Do 를 호출하지 않는 한 계속 실행됩니다exit 함수 또는 다른 프로세스 호출kthreadstop 함수로 라인의 운행을 끝냅니다.
그러나 루틴 함수가 매우 중요한 작업을 처리하고 있다면 중단되지 않을 것입니다.물론 스레드 함수가 영원히 되돌아오지 않고 신호를 검사하지 않으면 영원히 멈추지 않을 것이다.
1. 헤더 파일
[cpp] view plain copy print ?
#include    //wake_up_process()   
  •   

  • #include  //kthread_create()、kthread_run()   
  •   

  • #include  //IS_ERR()、PTR_ERR()  
    #include <linux/sched.h>   //wake_up_process()
    
    #include <linux/kthread.h> //kthread_create()、kthread_run()
    
    #include <err.h> //IS_ERR()、PTR_ERR()

    2. 실현
    2.1 스레드 생성
    kernel thread는kernelthread를 만듭니다. 그러나 실행 함수에서daemonize로 자원을 방출하고 init에 걸어야 합니다. 이 과정이 완성되기를 completion으로 기다려야 합니다.조작을 간소화하기 위해kthread크리에이트가 깜짝 등장했다.
    모듈을 초기화할 때 라인을 만들 수 있습니다.다음 함수와 매크로 정의를 사용합니다.
    [cpp] view plain copy print ?
    struct task_struct *kthread_create(int (*threadfn)(void *data),  
  •   

  •                             void *data,  
  •   

  •                             const char namefmt[], ...);  
    struct task_struct *kthread_create(int (*threadfn)(void *data),
    
                                void *data,
    
                                const char namefmt[], ...);

    kthread_create 원본 코드 상세 설명http://blog.sina.com.cn/s/blog_6237dcca0100gq67.html
    [cpp] view plain copy print ?
    #define kthread_run(threadfn, data, namefmt, ...)                     /  
  •   

  • ({                                                            /  
  •   

  •     struct task_struct *__k                                        /  
  •   

  •            = kthread_create(threadfn, data, namefmt, ## __VA_ARGS__); /  
  •   

  •     if (!IS_ERR(__k))                                        /  
  •   

  •            wake_up_process(__k);                                /  
  •   

  •     __k;                                                     /  
  •   

  • })  
    #define kthread_run(threadfn, data, namefmt, ...)                     /
    
    ({                                                            /
    
        struct task_struct *__k                                        /
    
               = kthread_create(threadfn, data, namefmt, ## __VA_ARGS__); /
    
        if (!IS_ERR(__k))                                        /
    
               wake_up_process(__k);                                /
    
        __k;                                                     /
    
    })

    예를 들면 다음과 같습니다.
    [cpp] view plain copy print ?
    static struct task_struct *test_task;  
  •   

  • static int test_init_module(void)  
  •   

  • {  
  •   

  •     int err;  
  •   

  •     test_task = kthread_create(test_thread, NULL, "test_task");  
  •   

  •     if(IS_ERR(test_task)){  
  •   

  •       printk("Unable to start kernel thread./n");  
  •   

  •       err = PTR_ERR(test_task);  
  •   

  •       test_task = NULL;  
  •   

  •       return err;  
  •   

  •     }  
  •   

  •     wake_up_process(test_task);  
  •   

  •     return 0;  
  •   

  • }  
  •   

  •         module_init(test_init_module);  
    static struct task_struct *test_task;
    
    static int test_init_module(void)
    
    {
    
        int err;
    
        test_task = kthread_create(test_thread, NULL, "test_task");
    
        if(IS_ERR(test_task)){
    
          printk("Unable to start kernel thread./n");
    
          err = PTR_ERR(test_task);
    
          test_task = NULL;
    
          return err;
    
        }
    
        wake_up_process(test_task);
    
        return 0;
    
    }
    
            module_init(test_init_module);

    2.2 스레드 함수
    스레드 함수에서 필요한 업무 논리 작업을 완성한다.기본 프레임은 다음과 같습니다.
    int threadfunc(void *data){
            …
            while(1){
                   set_current_state(TASK_UNINTERRUPTIBLE);
                   if(kthread_should_stop()) break;
    if () {//조건이 진짜입니다
    //업무 처리
                   }
    else{//조건은 가짜
    //CPU가 다른 스레드를 실행하도록 하고 지정된 시간 내에 재스케줄링됨
                          schedule_timeout(HZ);
                   }
            }
            …
            return 0;
    }
    2.3 종료 스레드
    모듈을 마운트 해제할 때 라인의 운행을 끝낼 수 있습니다.다음 함수를 사용합니다.
    int kthread_stop(struct task_struct *k);
    예를 들면 다음과 같습니다.
    [cpp] view plain copy print ?
                  static void test_cleanup_module(void)  
  •   

  • {  
  •   

  •             if(test_task){  
  •   

  •                 kthread_stop(test_task);  
  •   

  •                 test_task = NULL;  
  •   

  •             }  
  •   

  • }  
  •   

  • module_exit(test_cleanup_module);  
                  static void test_cleanup_module(void)
    
    {
    
                if(test_task){
    
                    kthread_stop(test_task);
    
                    test_task = NULL;
    
                }
    
    }
    
    module_exit(test_cleanup_module);

    3. 주의사항
    (1) kthread 호출stop 함수일 때, 스레드 함수는 이미 실행이 끝났을 수 없습니다.그렇지 않으면 kthreadstop 함수는 계속 기다립니다.
    (2) 스레드 함수는 다른 스레드를 실행할 수 있도록 CPU를 비켜야 한다.동시에 스레드 함수도 다시 스케줄링되어 실행되어야 한다.예시 프로그램에서 이것은 schedule 을 통해timeout () 함수가 완성되었습니다.
    4. 성능 테스트
    스레드(코어 스레드 포함)의 CPU 사용률을 확인하려면 top 명령을 사용합니다.명령은 다음과 같습니다.
    top – p 스레드 번호
    다음 명령을 사용하여 스레드 번호를 찾을 수 있습니다.
    ps aux|grep 스레드 이름 주석: 스레드 이름은kthreadcreate 함수의 세 번째 인자가 지정됩니다.
    코드:
    [cpp] view plain copy print ?
    #include    
  • #include    

  • #ifndef SLEEP_MILLI_SEC   
  • #define SLEEP_MILLI_SEC(nMilliSec)\  

  • do { \  
  • long timeout = (nMilliSec) * HZ / 1000; \  

  • while(timeout > 0) \  
  • { \  

  • timeout = schedule_timeout(timeout); \  
  • } \  

  • }while(0);  
  • #endif   

  • static struct task_struct * MyThread = NULL;  
  • static int MyPrintk(void *data)  

  • {  
  • char *mydata = kmalloc(strlen(data)+1,GFP_KERNEL);  

  • memset(mydata,'\0',strlen(data)+1);  
  • strncpy(mydata,data,strlen(data));  

  • while(!kthread_should_stop())  
  • {  

  • SLEEP_MILLI_SEC(1000);  
  • printk("%s",mydata);  

  • }  
  • kfree(mydata);  

  • return 0;  
  • }  

  • static int __init init_kthread(void)  
  • {  

  • MyThread = kthread_run(MyPrintk,"hello world","mythread");  
  • return 0;  

  • }  
  • static void __exit exit_kthread(void)  

  • {  
  • if(MyThread)  

  • {  
  • printk("stop MyThread");  

  • kthread_stop(MyThread);  
  • }  

  • }  
  • module_init(init_kthread);  

  • module_exit(exit_kthread);  
  • MODULE_AUTHOR("YaoGang");  
  • #include <linux/kthread.h>
    #include <linux/module.h>
    #ifndef SLEEP_MILLI_SEC
    #define SLEEP_MILLI_SEC(nMilliSec)\
    do { \
    long timeout = (nMilliSec) * HZ / 1000; \
    while(timeout > 0) \
    { \
    timeout = schedule_timeout(timeout); \
    } \
    }while(0);
    #endif
    static struct task_struct * MyThread = NULL;
    static int MyPrintk(void *data)
    {
    char *mydata = kmalloc(strlen(data)+1,GFP_KERNEL);
    memset(mydata,'\0',strlen(data)+1);
    strncpy(mydata,data,strlen(data));
    while(!kthread_should_stop())
    {
    SLEEP_MILLI_SEC(1000);
    printk("%s
    ",mydata); } kfree(mydata); return 0; } static int __init init_kthread(void) { MyThread = kthread_run(MyPrintk,"hello world","mythread"); return 0; } static void __exit exit_kthread(void) { if(MyThread) { printk("stop MyThread
    "); kthread_stop(MyThread); } } module_init(init_kthread); module_exit(exit_kthread); MODULE_AUTHOR("YaoGang");

    이 내부 라인의 역할은 1초 간격으로'hello world'를 출력하는 것이다.
    특히 kthreadshould_stop 함수, 열린 라인에 이 함수를 삽입하고 이 함수의 반환 값을 검사해야 합니다. 그렇지 않으면kthreadstop은 효과가 없어요.
    스레드(코어 스레드 포함)의 CPU 사용률을 확인하려면 top 명령을 사용합니다.명령은 다음과 같습니다.
    top – p 스레드 번호
    다음 명령을 사용하여 스레드 번호를 찾을 수 있습니다.
    ps aux|grep 스레드 이름

    좋은 웹페이지 즐겨찾기