内核版本3.x的线程上的Linux内核编程

时间:2013-10-17 10:30:05

标签: linux multithreading linux-kernel

我想知道在哪里可以找到针对内核3.x线程的Linux内核编程的优秀教程或示例?

任何帮助都会受到赞赏.....

1 个答案:

答案 0 :(得分:1)

我建议你在内核中挖掘推迟工作的几种方法(因为它最终是你需要的)。

与您明确要求的最接近的解决方案是使用

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

可能适合您的问题的另一种方法是使用工作队列。有了这个,你必须首先声明你想要推迟的工作。您可以使用两个预处理器宏来执行此操作,具体取决于您希望分配工作结构的位置:

  • 在堆栈上:DECLARE_WORK(name, void (*func)(void*), void *data);将使用struct work_struct工作人员函数自动初始化堆栈上的func,该函数将在运行时以data提供。
  • 在堆上:假设您已经分配了一个struct work_struct对象,而您只想用您的函数和合适的数据对其进行初始化。然后你应该使用INIT_WORK(struct work_struct *work, void (*func)(void*), void *data);

如果您希望运行任务,则必须计划,然后它将显示在相关的工作线程中运行的工作列表中工作队列。如果您只想使用默认工作队列,则必须使用以下两个函数之一:

int schedule_work(struct work_struct *work);
int schedule_delayed_work(struct work_struct *work, unsigned long delay);

delay jiffies (处理器时钟的滴答)表示。

如果您已创建自定义工作队列,则必须使用其他功能。但首先,让我们看看如何创建自己的工作队列对象。要实现这一目标,您只需致电:

struct workqueue_struct create_workqueue(const char *name);

完成后,您可以使用类似于之前显示的两个函数将待处理工作添加到队列中。

int queue_work(struct workqueue_struct *wq, struct work_struct *work);
int queue_delayed_work(struct workqueue_struct *wq,
    struct work_struct *work, unsigned long delay);

如果要刷新待处理作品列表,只需使用:

/* On the default work queue */
void flush_scheduled_work(void);

/* On a dynamically created work queue */
void flush_workqueue(struct workqueue_struct *wq);

请注意,这会记录尚未准备就绪的刷新延迟工作...如果您想取消延迟工作,则必须使用int cancel_delayed_work(struct work_struct *work);工作线程的行为如下:

  1. 虽然要运行的作品列表是非空的:
    1. 它抓住列表头部的工作(struct work_struct对象)。
    2. 它运行用对象func提供的对象data,如果工作结构存储在struct work_struct *work中,它将执行(*work->func)(work->data);
  2. 如果预定作品列表为空,则进入休眠状态。当你安排工作时,它会被唤醒。
  3. 显然,当您需要始终准备好运行后台任务时,第二个选项不适用。在这种情况下,标准kthread就是您所需要的。请参阅我链接的手册页,它解释了如何非常清楚地使用它。

    要解决您的问题,您可以运行两个线程。发件人和收件人。接收器接收传入的数据包(这可能比看起来更复杂,您可能必须处理irq handlers这样做...)。因此,kthread_create选项对您有好处。另一方面,当您获得要发送的数据(针对发件人)或刚刚收到适当的数据包时,您可以安排下半部分并运行 ONCE 收件人)。在这种情况下,您可能必须使用工作队列 tasklet (或 softirqs )。我将在稍后编辑我的帖子来描述这些野兽,因为我目前已经没时间了。