【问题标题】:Linux kernel programming on threads for kernel version 3.x内核版本 3.x 在线程上的 Linux 内核编程
【发布时间】:2013-10-17 10:30:04
【问题描述】:

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

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

【问题讨论】:

  • 嗯?您无需在内核内部编程即可使用pthreads;并且内核线程非常复杂,您可能应该避免使用它们。转至kernelnewbies.org
  • @BasileStarynkevitch 我正在处理需要同时发送和接收数据包并且必须在内核级别完成的项目。这就是为什么我正在寻找内核级别的线程。我在内核新手发现了这个 [thread] (kernelnewbies.org/Simple_UDP_Server?highlight=%28thread%29) 示例,但它适用于较旧的内核版本。我正在为更新的内核寻找更多这样的例子......

标签: linux multithreading linux-kernel


【解决方案1】:

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

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

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

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

  • 在堆栈上:DECLARE_WORK(name, void (*func)(void*), void *data); 将使用func 工作函数在堆栈上自动初始化一个struct work_struct,该工作函数将在运行时提供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)。我稍后会编辑我的帖子来描述这些野兽,因为我现在时间不多了。

【讨论】:

  • 非常感谢您的回答。我一直在寻找类似于khtread的东西......但我也会查看工作队列并阅读,也许工作队列可以比Kthread更容易解决我......再次非常感谢你的回答......跨度>
  • 我暂时无法做出更好的回答,但我会尽快对其进行编辑。小心真正了解不同解决方案之间的差异。
猜你喜欢
  • 1970-01-01
  • 2011-07-15
  • 1970-01-01
  • 2023-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-21
  • 1970-01-01
相关资源
最近更新 更多