1

我想知道在哪里可以找到关于内核 3.x 线程的 linux 内核编程的好教程或示例?

任何帮助,将不胜感激.....

4

1 回答 1

1

我建议您研究几种在内核中延迟工作的方法(因为这是您最终需要的)。

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

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

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

  • 在堆栈上:DECLARE_WORK(name, void (*func)(void*), void *data);将使用工作函数自动在堆栈上初始化 a 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);

delayjiffies(处理器时钟的滴答声)表示。

如果您创建了自定义工作队列,则必须使用其他功能。但首先,让我们看看如何创建自己的工作队列对象。为此,您只需调用:

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. 如果计划的工作列表为空,则进入睡眠状态。当您安排工作时,它将被唤醒。

显然,当您需要始终准备好运行后台任务时,第二个选项不适合。在这种情况下,kthread您需要一个标准。请参阅我链接的手册页,它非常清楚地解释了如何使用它。

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

于 2013-10-18T07:03:57.817 回答