Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3514329
  • 博文数量: 1805
  • 博客积分: 135
  • 博客等级: 入伍新兵
  • 技术积分: 3345
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-19 20:01
文章分类

全部博文(1805)

文章存档

2017年(19)

2016年(80)

2015年(341)

2014年(438)

2013年(349)

2012年(332)

2011年(248)

分类: LINUX

2014-10-23 15:47:19

原文地址:linux 进程等待超时 作者:ssdx1986

    想在linux内核写一个程序,这个程序主要功能是等待一个semaphore,但是如果semaphore在一定的时间内没到这个程序执行后面的操作。
    但是在网上找了很多都是使用以下这些的。
  sem_init:初始化信号量sem_t,初始化的时候可以指定信号量的初始值,以及是否可以在多进程间共享。
sem_wait:一直阻塞等待直到信号量>0。
sem_timedwait:阻塞等待若干时间直到信号量>0。
sem_post:使信号量加1。
sem_destroy:释放信号量。和sem_init对应。
我用这些在内核中使用,一直是有问题,我想这个可能是在用户空间使用。这个的用法我觉得他写的挺好的。http://blog.csdn.net/dog_in_yellow/article/details/2041065

经过多方的查找终于找到了。决定使用wait_event_interruptible_timeout这个超时函数。在驱动程序中通常使用等待队列来等待其他事件,同时希望在待定的时间段中自动运行程序。一般有wait_event_interruptible_timeout和wait_event_timeout这两个函数。
long wait_event_interruptibe_timeout(wait_queue_head_t q,condition,long timeout);
返回值是>0,表示condition 为真,唤醒了待队列,程序运行。返回值为0表示超时,程序运行。
在实验当中发现唤醒队列的方式只要condition为真就是,不需要wake_up这个函数。但是有人说可以使用wake_up这个方式进行唤醒队列,如果有哪位仁兄知道怎么回事麻烦告诉我下。
不哆嗦把小实验写上,看的更明白。



#include
#include
#include
#include
#include
#include
#include
#include

wait_queue_head_t select_wait;
static int num=1;

void hello()
{
    int val=0;
    while(1){
            printk("ddddd\n");
                                schedule_timeout_uninterruptible(100);
            val =    wait_event_interruptible_timeout(select_wait,num,20000);
            printk("fffff\n");
            num=0;
            if (val==0)
                printk("val ==0\n");
            else
                printk("val =%d\n",val);
    }
}
void ok()
{
    printk("0k\n");
    while(1){
                schedule_timeout_uninterruptible(400)
;
                if(waitqueue_active(&select_wait)){//其实这个if语句直接用num =1,就行。wake_up_interruptibe(&select_wait)感觉没有效果。
                    num=1;
                    wake_up_interruptible(&select_wait);
                    printk("wake up\n");
                }
    }
}

int HS_init(void)
{
    init_waitqueue_head(&select_wait);    
    int res = 0;
    printk(KERN_ALERT "Hello ...\n");
    kernel_thread(hello,NULL,CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
    kernel_thread(ok,NULL,CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
    return res;
}



void HS_exit(void)
{
    num=0;
    printk(KERN_ALERT "Bye ...\n");
}
static int __init hsdrv_init(void)
{
    printk(KERN_ALERT " driver loading ...\n");
    return HS_init();
    
}


static void __exit hsdrv_exit(void)
{
    printk(KERN_ALERT "HS driver unloaded.\n");
    HS_exit();
}
MODULE_LICENSE("GPL");
module_init(hsdrv_init);
module_exit(hsdrv_exit);




阅读(1521) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~