【问题标题】:Wake up a Kthread which is sleeping唤醒一个正在休眠的 Kthread
【发布时间】:2021-09-11 14:08:51
【问题描述】:
static struct task_struct *control = NULL;
static long call_ioctl(struct file *filp, unsigned int iocmd, unsigned long arg) 
{
    switch (iocmd)
    {
        case SETMODE:
            /* get buffer data from userspace which is either 0 or 1 */
            /* 0: Manual 1: Automatic*/
            switch (buffer)
            {
            case MANUAL:
                if (control)
                {
                    kthread_stop(control);
                    control = NULL;
                    printk(KERN_ALERT "Switching to MANUAL disabling kernel thread for Automatic\n");
                }
                mode = MANUAL_MODE;
                printk(KERN_ALERT "IN MANUAL \n");
                break;

            case AUTOMATIC:
            if (automatic_fan_control() != 0)
            {
                printk(KERN_ALERT "Failed to set fan to  AUTOMATIC!!! \n");
                return -1;
            }
            break;

            default:
                printk(KERN_ALERT "Entered value is incorrect\n");
                return -EINVAL;
            }
        break;
    }
       
}

static inline int automatic_fan_control(void)
{
    control = kthread_run(sense_cpu_temperature, NULL, "Temperature Thread");
    if (control)
    {
        printk(KERN_ALERT "Kthread Created Successfully\n");
    }
    else
    {
        printk(KERN_ALERT "Failed to create kthread. \n");
        control = NULL;
        return -1;
    }
    return 0;
}

int temperature(void *arg)
{

    while (!kthread_should_stop())
    {
        mutex_lock(&mutex);
        get_temperature();
        mutex_unlock(&mutex);
        /* Process the temperature value */
        msleep_interruptible(polling_interval);
    }
    return 0;
}

这是我为驱动程序编写的上述代码:

  • 当我切换到自动模式时,会创建线程来获取温度并对其进行处理,一旦完成,它将休眠 polling_interval 时间,然后在时间过去后再次处理。
  • 当我切换到手动模式时,必须停止 kthread 并进入不是线程的手动模式。
  • 我这里面临的问题是切换到手动模式时,它会在kthread的睡眠时间完成后响应,如果提供的睡眠时间间隔很大,切换到手动模式需要很长时间。
  • kthread 切换到手动模式时,有什么方法可以从睡眠中退出。有点卡在这个新手驾驶中,任何帮助都会很棒

【问题讨论】:

  • 旁白:automatic_fan_control 需要处理已经自动的风扇控制,以避免不必要地创建另一个线程。否则代码会泄漏线程。
  • @IanAbbott:谢谢,会处理这个问题,关于如何从睡眠中唤醒线程的任何输入或参考?

标签: c linux-kernel kernel linux-device-driver


【解决方案1】:

我们来看看msleep_interruptible的出处:

unsigned long msleep_interruptible(unsigned int msecs)
{
        unsigned long timeout = msecs_to_jiffies(msecs) + 1;

        while (timeout && !signal_pending(current))
                timeout = schedule_timeout_interruptible(timeout);
        return jiffies_to_msecs(timeout);
}

schedule_timeout_interruptible 进入休眠状态,直到超时到期,或传递信号,或显式唤醒。它以 jiffies 的形式返回剩余时间。如上所示,msleep_interruptible 如果提早唤醒并且没有信号待处理,将重新进入睡眠状态。

kthread_stop 显式唤醒线程任务,但不发送信号,因此msleep_interruptible 将运行完成,如果提早唤醒,则将线程任务重新休眠。

在这种情况下,一个简单的解决方法是替换 temperature 中的这个调用:

        msleep_interruptible(polling_interval);

通过以下调用:

        schedule_timeout_uninterruptible(msecs_to_jiffies(polling_interval) + 1);

那么,如果早起,它就不会再睡了。

【讨论】:

  • 将 msleep_interruptible(polling_interval) 替换为 schedule_timeout(msecs_to_jiffies(polling_interval) + 1),通过这样做,我观察到线程没有等待 polling_interval,它继续连续执行,没有任何延迟。 polling_interval 总是在几秒到 120 秒左右,即使有这个时间间隔,线程也会连续执行。
  • @Manu 抱歉,schedule_timeout 似乎没有改变任务状态。请致电schedule_timeout_uninterruptibleschedule_timeout_interruptible
猜你喜欢
  • 2014-08-02
  • 1970-01-01
  • 2012-08-15
  • 2015-05-28
  • 2011-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多