内核线程与计时器

时间:2010-12-06 15:59:38

标签: linux-kernel kernel

我正在编写一个使用定制的屏幕打印系统的内核模块。基本上每次涉及print时,字符串都会插入到链接列表中。 每隔X秒,我需要处理列表并在打印它们之前对字符串执行一些操作。

基本上我有两种选择来实现这样的过滤器:

1)定时器(最后重启)

2)内核线程,它休眠X秒

虽然过滤器正在执行其中没有其他东西可以使用链接列表,当然,在插入字符串时,过滤器函数应该等待。

AFAIK计时器在中断上下文中运行,因此它无法休眠,但内核线程呢?他们可以睡觉吗?如果是,是否有一些理由不在我的项目中使用它们?可以使用哪种其他解决方案?

总结一下:我的过滤功能只有3个要求:

1)必须能够printk

2)当使用列表时,尝试访问列表的其他所有内容都必须阻塞,直到过滤器函数完成执行

3)必须每X秒运行一次(不是实时要求)

2 个答案:

答案 0 :(得分:2)

允许kthreads睡觉。 (但是,并非所有kthread都为所有客户端提供了睡眠执行。例如,softirqd不会。) 但话说回来,你也可以使用自旋锁(及其相关的成本)并且没有额外的线程(这基本上是定时器所做的,使用spinlock_bh)。这真是一个权衡。

答案 1 :(得分:1)

  

每次涉及print时,字符串都会插入到链接列表中

我真的不知道你的意思是print还是printk。但是如果你在谈论printk(),你需要分配内存并且你遇到麻烦,因为printk()可能在原子上下文中被调用。这使您可以选择使用循环缓冲区(因此,您应该容忍丢弃一些字符串,因为您可能没有足够的内存来保存所有字符串)。

  

每隔X秒,我需要处理列表并在打印字符串之前对字符串执行一些操作。

在这种情况下,我甚至不会做内核线程:如果代价太高,我会在print()进行处理。

否则,我会创建一个新的系统调用:

  • sys_get_strings()或其他东西,它会将整个链表转储到用户空间中(并在复制时从列表中删除条目)。

这样整个行为就由用户空间控制。你可以创建一个每X秒调用一次系统调用的守护进程。您还可以在用户空间中进行所有昂贵的处理。

您还可以创建一个新设备/dev/print-on-screen

  • dev_open会分配内存,而print()将不再是无操作,但会在设备预先分配的内存中提供数据(如果使用print()在原子上下文和所有)。
  • dev_release会抛出一切
  • dev_read会为您提供字符串
  • dev_write可以在您的屏幕打印系统上执行某些操作