linux内核wait_event_interruptible和wake_up_interruptible的使用,实现内核两个进程间的交互

内核中使用wait_event_interruptible和wake_up_interruptible接口函数,来实现内核两个进程之间的交互。

代码实现:

/* 声明一个工作队列入等待*/
static DECLARE_WAIT_QUEUE_HEAD(my_wq);

static volatile int wq_condition = 0;


void thread1()
{
    for(;;){
        /*进入休眠等待*/
        wait_event_interruptible(my_wq, wq_condition );
    }
}

void thread2()
{
    wq_condition = 1;
    /*唤醒休眠的进程*/
    wake_up_interruptible(&my_wq);
}

DECLARE_WAIT_QUEUE_HEAD宏定义解析:

1. 功能:创建以个等待队列头

2. 函数原型

#define DECLARE_WAIT_QUEUE_HEAD (name)                            /

    wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name)



#define __WAIT_QUEUE_HEAD_INITIALIZER (name) {                    /

    .lock       = __SPIN_LOCK_UNLOCKED(name.lock),               /

    .task_list = { &(name).task_list, &(name).task_list } }


typedef struct __wait_queue_head wait_queue_head_t ;

struct __wait_queue_head {

    spinlock_t lock;

    struct list_head task_list;

};

wake_up_interruptible 函数解析:

功能:唤醒注册到等待队列上的进程

原型

    #include
    void wake_up_interruptible (wait_queue_head_t *q);

说明
    唤醒 q 指定的注册在等待队列上的进程。该函数不能直接的立即唤醒进程,而是由调度程序转换上下文,调整为可运行状态

变量
q :  等待队列变量指针

 

wait_event_interruptible函数解析:

功能:将当前进程挂起,从运行态队列移出,进入休眠态

原型



    #define wait_event_interruptible(wq, condition)          \
    ({                                                       \
        int __ret = 0;                                       \
        if (!(condition))                                    \
            __wait_event_interruptible(wq, condition, __ret);\
        __ret;                                               \
    })

    #define __wait_event_interruptible(wq, condition, ret)                        \
    do {                                                                        \
            DEFINE_WAIT(__wait);                                                \
                                                                            \
            for (;;) {                                                        \
                    prepare_to_wait(&wq, &__wait, TASK_INTERRUPTIBLE);        \
                    if (condition)                                                \
                            break;                                                \
                    if (!signal_pending(current)) {                                \
                            schedule();                                        \
                            continue;                                        \
                    }                                                        \
                    ret = -ERESTARTSYS;                                        \
                    break;                                                        \
            }                                                                \
            finish_wait(&wq, &__wait);                                        \
    } while (0)

wait_event_interruptible()这个函数先将当前进程的状态设置成TASK_INTERRUPTIBLE,然后调用schedule(),而schedule()会将位于TASK_INTERRUPTIBLE状态的当前进程从runqueue队列中删除。从runqueue队列中删除的结果是,当前这个进程将不再参
与调度,除非通过其他函数将这个进程重新放入这个runqueue队列中,这就是wake_up()的作用了。
  
由于这一段代码位于一个由condition控制的for(;;)循环中,所以当由shedule()返回时(当然是被wake_up之后,通过其他进程的schedule()而再次调度本进程),如果条件condition不满足,本进程将自动再次被设置为TASK_INTERRUPTIBLE状态,接下来执行schedule()的结果是再次被从runqueue队列中删除。这时候就需要再次通过wake_up重新添加到runqueue队列中。
如此反复,直到condition为真的时候被wake_up.
  
可见,成功地唤醒一个被wait_event_interruptible()的进程,需要满足:
  
1)condition为真的前提下,2) 调用wake_up()。
  
2. 关于wait_event_interruptible的返回值
  
根据 wait_event_interruptible 的宏定义知:
  
   1) 条件condition为真时调用这个函数将直接返回0,而当前进程不会
      被 wait_event_interruptible和从runqueue队列中删除。
  
   2) 如果要被wait_event_interruptible的当前进程有nonblocked pending
      signals, 那么会直接返回-ERESTARTSYS(i.e. -512),当前进程不会
      被wait_event_interruptible 和从runqueue队列中删除。
  
   3) 其他情况下,当前进程会被正常的wait_event_interruptible,并从
      runqueue队列中删除,进入TASK_INTERRUPTIBLE状态退出运行调度,
      直到再次被唤醒加入runqueue队列中后而参与调度,将正常返回0。

 

参考文章:

1.

https://blog.csdn.net/allen6268198/article/details/8112551?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param

2. https://www.cnblogs.com/jingzhishen/p/4208501.html

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值