华清远见嵌入式学习day35——IO模型

【1】复习

    1. led驱动
    
        readl & writel
        
    2. regster_chrdev & unregister_chrdev
    
    3. 
        kmalloc kzalloc kfree
    
        vmalloc vzalloc vfree
        
        __get_free_page & __get_free_pages
        
            --->>> get_order();
            
    4. 并发竟态
    
        同步互斥
        
        中断屏蔽
        自旋锁
        原子操作
        ===========================
        信号量
        互斥体
【2】作业

【一】、信号量

    <linux/semaphore.h>
    
    struct semaphore  信号量结构体数据类型
    
    //初始化信号量的值
    void sema_init(struct semaphore *sem, int val)
    
    //减操作
    void down(struct semaphore *sem);
    //可中断(被信号)
    int  down_interruptible(struct semaphore *sem);
    //加操作
    void up(struct semaphore *sem);
    
    down();   --->>>  减失败 --->>> 进程睡眠  (down -->>> D(进程状态))
    down_interruptible()  减失败 --->>> 进程睡眠  (down -->>> S(进程状态))
    临界区
    up();


【二】、互斥体

    <linux/mutex.h>
    
    struct mutex //互斥体数据类型

    mutex_init(struct mutex * mutex)  //初始化互斥体
    
    //上锁
    void  mutex_lock(struct mutex *lock)
    //解锁
    void  mutex_unlock(struct mutex *lock)
    
    
    mutex_lock()
    临界区 
    mutex_unlock();

    
【三】、IO模型 

    阻塞  --->>>  进程休眠(D S)
    
        条件不满足的时候,进程休眠等
    
    非阻塞 
    
        条件不满足的时候,错误返回
        
    
    IO多路复用
    
    异步通知

【四】、阻塞

    1. 找一个固定的地方 --->>>  等待队列头 wait_queue_head_t
        
        //定义并初始化等待队列头(变量名)
        #define DECLARE_WAIT_QUEUE_HEAD(name)         \
            wait_queue_head_t name = {                \
                .lock        = __SPIN_LOCK_UNLOCKED(name.lock),        \
                .task_list    = { &(name).task_list, &(name).task_list } 
            }
    
        //初始化等待队列头
        init_waitqueue_head(wait_queue_head_t *q)
    
    2. 定义一个等待队列项 --- wait_queue_t
    
        --->>> 进程相关信息(task_struct)
        
       /*******************************************************************
        *功能:初始化等待队列项
        *参数:
        *            @q   等待队列项结构体指针
        *            @p   task_struct结构体指针
        *返回值:void
        ******************************************************************/
        void init_waitqueue_entry(wait_queue_t *q, struct task_struct *p)
        
    3. 将等待队列项挂在等待队列头上
        //将等待队列项挂在等待队列头上 
        void add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);
    
    4. 设置进程的状态  --->>> S/D
    
        <linux/sched.h>
    
        set_current_state(state_value)
        
        TASK_RUNNING
        TASK_INTERRUPTIBLE
        TASK_UNINTERRUPTIBLE
    
    5. -----调度 ------
    
        void schedule(void)
    
    6. 一旦唤醒,往下执行
    
    7. 将等待队列项从等待队列头移除
    
        void remove_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);
    
    8. 设置进程的状态 (R)
    
      --->>> 读数据
    
---------------------------条件满足----------------------------------    
    
    1. 唤醒
    
    wake_up(wait_queue_head_t *x)
    wake_up_interruptible(wait_queue_head_t *x)
    
    
=======================================================================================

    1. 简化版的阻塞实现
    
       /**************************************************
        *功能:实现阻塞   --->>> D :不可中断睡眠态
        *参数: 
        *        @wq             
        *        @condition      阻塞条件(非零为真)
        *************************************************/
        wait_event(wait_queue_head_t wq, condition)
        wait_event_interruptible(wq, condition)    
    

【五】、非阻塞

    条件不满足的时候,错误返回
    
        return -errno;
        
    O_NONBLOCK 
    
    open("xxxx",O_RDWR | O_NONBLOCK); --->>> struct file
    
    struct file {
        unsigned int f_flags;
    }
    
    
    if(filp->f_flags & O_NONBLOCK){
        return -errno;
    }    

    

【六】、IO多路复用 

    1. 网络学习IO多路复用
    
        select poll epoll  --->>> io多路复用的接口 
        
    2. 解决什么问题 
    
    
    server:                       client:
    
    int main()                    int main()
    {                            {
        socket();                    socket();
        bind();                        ...
        accept();                    connet();
        ...
        while(1){                    while(1){
            gets();                        
            
            send();                        recv();
                                        gets();
            recv();                        send();
        }                            }
    }                            }

    
    gets 和 recv 相互阻塞的问题
    
    gets :  条件不满足阻塞  ,  条件满足,从标准输入获取数据
    recv :     条件不满足阻塞  ,  条件满足,接收数据
    
    wait()监控gets和recv的阻塞,如果其中有一个返回,wait返回,否则阻塞
    
    server:                       client:
    
    int main()                    int main()
    {                            {
        socket();                    socket();
        bind();                        ...
        accept();                    connet();
        ...
        while(1){                    while(1){
            wait(0,sockfd);                wait(0,sockfd);
            
            gets();                        if(gets条件满足)
                                            gets();send();
            send();                        if(recv条件满足)
                                            recv();
            recv();                        
        }                            }
    }                            }
    
    
    --->>> read 阻塞   select()  --->>> man select
    
    int select(int nfds, fd_set *readfds, fd_set *writefds,
                  fd_set *exceptfds, struct timeval *timeout);
    
    条件满足或不满足是驱动知道 

    select --->>> 调用驱动的某一个接口来确定是否条件满足
    
    找到驱动的io多路复用接口 --->>> 完成接口
    
    (open --->>> fops->open)
    select --->>> fops -> poll
    
    fs/select.c 
    
    SYSCALL_DEFINE5(select, int, n, fd_set __user *, inp, fd_set __user *, outp,                                     
        fd_set __user *, exp, struct timeval __user *, tvp)
        
        --->>> core_sys_select(n, inp, outp, exp, to);
    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值