首页 > 解决方案 > 如何立即将 linux workqueue worker 的 printk 打印到 dmesg 中?

问题描述

我有一个关于 linux 工作队列的问题。我找到了使用工作队列的示例内核模块并对其进行了测试。这是代码。

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/workqueue.h>
#include <linux/slab.h>

MODULE_LICENSE( "GPL" );

static struct workqueue_struct *my_wq;

typedef struct {
    struct work_struct my_work;
    int    x;
} my_work_t;

my_work_t *work, *work2;


static void my_wq_function( struct work_struct *work)
{
    my_work_t *my_work = (my_work_t *)work;

    printk( "my_work.x %d", my_work->x );

    kfree( (void *)work );

    return;
}

static int __init init_workqueue( void )
{
    int ret;

    my_wq = create_workqueue("my_queue");
    if (my_wq) {

        /* Queue some work (item 1) */
        work = (my_work_t *)kmalloc(sizeof(my_work_t), GFP_KERNEL);
        if (work) {

            INIT_WORK( (struct work_struct *)work, my_wq_function );

            work->x = 1;

            ret = queue_work( my_wq, (struct work_struct *)work );

        }

        /* Queue some additional work (item 2) */
        work2 = (my_work_t *)kmalloc(sizeof(my_work_t), GFP_KERNEL);
        if (work2) {

            INIT_WORK( (struct work_struct *)work2, my_wq_function );

            work2->x = 2;

            ret = queue_work( my_wq, (struct work_struct *)work2 );

        }

    }

    return 0;
}

static void __exit exit_workqueue( void )
{
    flush_workqueue( my_wq );
    destroy_workqueue( my_wq );

    return;
}

module_init(init_workqueue)
module_exit(exit_workqueue)

这就是结果。左边显示我输入的内容,右边显示 dmesg。我不知道为什么 work2 的 printk 没有出现。

work.x 2 不显示

在我重新插入我的模块后,它就会出现。

诡异的

如何从排队的工作中获取 printk 消息?

标签: clinuxlinux-kernelworkqueue

解决方案


您的调用printk()不以换行符 ( \n) 结束,因此dmesg在下一次调用在内核消息缓冲区中添加新条目之前不会打印任何内容。

只需在格式字符串的末尾添加一个换行符,如下所示:

printk("my_work.x %d\n", my_work->x);
//                  ^^

推荐阅读