驱动开发学习day4-->阻塞 非阻塞 poll机制 异步

本文探讨了设备驱动中的阻塞操作、非阻塞I/O以及poll和异步IO机制。通过实例讲解了如何在驱动层实现等待队列和唤醒进程,以及非阻塞操作的处理策略。重点介绍了poll机制的原理和使用,以及异步IO如何利用信号通知提高效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 阻塞

 阻塞操作:是指在执行设备操作时,若不能获得资源,则挂起进程直到满足可操            作条件后在进行操作。
        read()-->HelloRead
        驱动中如何实现阻塞?可以定义一个休眠等待队列
        wait_queue_head_t  q;//定义一个休眠等待队列头
        init_waitqueue_head(&q);//初始化休眠等待队列
      使用:helloRead:
        wait_event_interruptible(q,con)-->使请求读数据的进程休眠--》休眠期可被                中断
        wait_event(q,con)-->休眠期不能被中断

 HelloWrite:-->写入数据后唤醒读进程读数据
    wake_up_interruptible(&q);-->唤醒可被中断的休眠进程
    wake_up;
    con=1;

        con:休眠进程进程的唤醒条件:1 唤醒  0 休眠
        注:当进程正常运行时,进程在运行对列中等待被运行。
    当进程休眠时,进程在休眠等待队列中等待被唤醒运行

2 非阻塞

非阻塞操作:是指在不能进行设备操作时,并不休眠或挂起进程,而是给请求进程立        即返回一个非正确的值,底层设备驱动通过不停的查询设备操作是否可进行    ,直到操作可进行后返给请求进程一个正确的结果。
  read-->非阻塞
   应用层:open("dev/haha0",O_RDWR|O_NONBLOCK);

驱动层:HelloRead()
    if(设备中没有数据可读)
    {
        if(应用层传入了O_NONBLOCK标志)
        {
        给应用程序返回非正确的值
        }
        else
        {
        阻塞进程;
        }    
    }
    else
    阻塞

    g_charcount:表示实际写入到内核中的字符个数

3 poll机制

 io多路复用--》select poll epoll
     HelloPoll(struct file *pFile, struct poll_table_struct *ptable)

 实现:1 将监控文件描述符的进程放入监控队列--》poll_wait(pFile,&q,ptable)
    ptable:轮询表
    将当前操作文件的进程加入到休眠等待队列中,将该队列加入到ptable.
    2 系统对监控队列中的修眠进程监控,若休眠进程的文件描述符上有IO数据发生,系统会将该进程激活。
    return mask;
    mask:用来描述操作是否可以立即无阻塞执行的位掩码
    mask:是一个32bits的整数,它的没每一个bit位代表了设备的一种操作状态(每一个BIT位都可以用一个宏来表示)
    POLLIN:有数据可读
    POLLRDNORM:有普通数据可读
    POLLOUT:有数据可写
    POLLERR:指定文件描述符发生错误

4 异步IO

异步IO:读进程去设备中读数据,设备没有数据可读,那么当前进程阻塞,若内核检测到设备有数据可读时,会给读进程发送通知信号,读进程会执行该信号对应的处理动作去读数据。
应用:

        A(读数据进程)
            1 注册一个信号处理函数 signal(SIGIO,hander);
            2 打开设备文件 fd=open("/dev/haha0",...);
            3 设置文件描述符的宿主 fcntl(fd,F_SETOWN,getpid());
            4 读取文件描述符的标志 int flags=fcntl(fd,F_GETFL);
            5 设置文件描述符标志 fcntl(fd,F_SETFL,flags|FASYNC)->异步通知标志
            while(1);
            hander-->read()
            注:fcntl:是系统调用函数,用来设置或获取文件描述符的属性

        B(写数据进程)
            1 open("/dev/haha0");
            2 write-->helloWrite-->给读进程发信号
            3 close

驱动:

            1 HelloFasync
                1 定义一个全局的异步通知结构体--》关联信号发送方和接收方
                2 初使化异步通知结构体
                fasync_helper(fd,pFile,on,&fasync)
            2 HelloWrite
               kill_fasync(&fasync,SIGIO,POLL_IN);

               SIGIO-->fasync-->fd(读)--》getpid()==A

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值