如何在 Linux 中多次排队相同的工作队列工作?

How to queue the same workqueue work multiple times in Linux?

我看到调用 schedule_work 函数时,如果工作任务已经排队,它不会将其放入队列。但是我想将同一个任务排队 运行 多次,即使它已经在队列中了。我该怎么做?

来自workqueue.h:

/**
 * schedule_work - put work task in global workqueue
 * @work: job to be done
 *
 * Returns %false if @work was already on the kernel-global workqueue and
 * %true otherwise.
 *
 * This puts a job in the kernel-global workqueue if it was not already
 * queued and leaves it in the same position on the kernel-global
 * workqueue otherwise.
 */
static inline bool schedule_work(struct work_struct *work)

Workqueue 期望每个 work 结构代表 单个 "task",需要 运行 一次。

因此,最简单的方法是多次 运行 一个任务 - 每次都创建新的 work 结构。

或者,由于在 运行ning 时重复工作对于工作队列来说不寻常,您可以创建自己的内核线程来重复执行某些功能:

DECLARE_WAITQUEUE(repeat_wq); // Kernel thread will wait on this workqueue.
int n_works = 0; // Number of work requests to process.

// Thread function
void repeat_work(void* unused)
{
    spin_lock_irq(repeat_wq.lock); // Reuse workqueue's spinlock for our needs
    while(1) {
        // Wait until work request or thread should be stopped
        wait_event_interruptible_locked(&repeat_wq,
            n_works || kthread_should_stop());
        if(kthread_should_stop()) break;
        spin_unlock_irq(repeat_wq.lock);

        <do the work>

        // Acquire the lock for decrement count and recheck condition
        spin_lock_irq(repeat_wq.lock);
        n_works--;
    }
    // Finally release the lock
    spin_unlock_irq(repeat_wq.lock);
}

// Request new work.
void add_work(void)
{
    unsigned long flags;
    spin_lock_irqsave(repeat_wq.lock, flags);
    n_works++;
    wake_up_locked(&repeat_wq);
    spin_unlock_irqrestore(repeat_wq.lock, flags);      
}

工作队列也是内核线程,具有特定的线程函数kthread_worker_fn()