简单的内核多线程

问题描述 投票:0回答:3

我是内核模块编程的新手,为了我的工作,我需要编写一个多线程内核模块。所以我尝试了内核线程的一些主要用途。我写了以下内容。它应该在一个线程中打印 1,在另一个线程中打印 2,都打印 10 次。

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/udp.h>
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/kthread.h>

struct task_struct *task1;
struct task_struct *task2;


static void thread_func(void* data)
{   
    int *n;
    n = (int *)data;
    int i = 0;
    while(i < 10){
        printk("%d\n", *n);
        i++;
    }
    //do_exit();
}

static int t_start(void)
{
    printk("Module starting ... ... ..\n");
    int *p1, *p2;
    int one = 1, two = 2;
    p1 = &one;
    p2 = &two;
    task1 = kthread_run(&thread_func, (void*)p1, "thread_func_1");
    task2 = kthread_run(&thread_func, (void*)p2, "thread_func_2");
    return 0;
}

static void t_end (void)
{
    printk("Module terminating ... ... ...\n");
    kthread_stop(task1);
    kthread_stop(task2);
}

module_init(t_start);
module_exit(t_end);

MODULE_AUTHOR("Md. Taufique Hussain");
MODULE_DESCRIPTION("Testing kernel threads");
MODULE_LICENSE("GPL");

但是我面临以下问题。 -

  1. 第一个线程打印所有十个 1,然后第二个线程打印 执行。我想以交错的方式运行这两个。
  2. 第一个线程打印所有 1,但第二个线程不打印 2。它 正在打印 0。可能参数没有传递给第二个线程 正确地。
  3. 当我插入模块时它正在运行,但是当我删除时 模块机器挂了

存在哪些问题?我该如何解决这些问题。

multithreading linux-kernel kernel-module
3个回答
4
投票
  1. 不要使用这些代码,删除它们
// kthread_stop(task1);
// kthread_stop(task2);

看来线程终止后,task会被设置为NULL,然后调用

kthread_stop()
会导致空指针错误

  1. 不要将局部变量传递给线程,而是使用全局变量。

  2. 如果您希望两个线程相互切换,请使用

    wait_event()
    wake_up()
    函数。这是我的有效代码。

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/wait.h>

MODULE_LICENSE("GPL");

int pid1 = 1;
int pid2 = 2;

DECLARE_WAIT_QUEUE_HEAD(wq);

int condition;

struct task_struct *task1;
struct task_struct *task2;

static int thread_function(void *data)
{
    int *thread_id = (int *)data;
    int i = 0;
    while (i < 10) {
        printk(KERN_INFO "install kernel thread: %d\n", *thread_id);
        i++;

        if (*thread_id == 1) {
            wait_event(wq, condition == 0xA);

            condition = 0xB;
            wake_up(&wq);
        } else {
            wait_event(wq, condition == 0xB);

            condition = 0xA;
            wake_up(&wq);
        }
    }
    return 0;
}

static int kernel_init(void)
{
    condition = 0xA;

    task1 = kthread_create(&thread_function, (void *)&pid1, "pradeep");
    task2 = kthread_create(&thread_function, (void *)&pid2, "pradeep");

    // printk(KERN_INFO "After create kernel thread\n");
    wake_up_process(task1);
    wake_up_process(task2);
    return 0;
}

int init_module(void)
{
    kernel_init();
    return 0;
}

void cleanup_module(void)
{
}

3
投票
  1. 你需要schedule(),除非你有一个可抢占的内核并且有一些睡眠。
  2. 您正在从堆栈传递数据指针,从而损坏内核内存。将这些 int 设为全局变量。

2
投票

添加

schedule
调用以强制线程调度。

static void thread_func(void* data)
{   
    int *n;
    n = (int *)data;
    int i = 0;
    while(i < 10){
        printk("%d\n", *n);

        schedule();

        i++;
    }
    //do_exit();
}
© www.soinside.com 2019 - 2024. All rights reserved.