当前位置:  技术问答>linux和unix

有关驱动开发里面队列的问题

    来源: 互联网  发布时间:2016-11-16

    本文导语:  static ssize_t globalfifo_write(struct file *filp,const char __user *buf,size_t count,loff_t *ppos) { int ret; DECLARE_WAITQUEUE(wait,current); down(&globalfifo_devp->sem); add_wait_queue(&globalfifo_devp->w_wait,&wait); if(globalfifo_devp->current_len==GLOBALFIFO_SIZE) { if(fi...



static ssize_t globalfifo_write(struct file *filp,const char __user *buf,size_t count,loff_t *ppos)
{
int ret;
DECLARE_WAITQUEUE(wait,current);
down(&globalfifo_devp->sem);
add_wait_queue(&globalfifo_devp->w_wait,&wait);
if(globalfifo_devp->current_len==GLOBALFIFO_SIZE)
{
if(filp->f_flags & O_NONBLOCK)
{
ret=-EAGAIN;
goto out;
}
__set_current_state(TASK_INTERRUPTIBLE);
up(&globalfifo_devp->sem);

schedule();
if(signal_pending(current))
{
ret=-ERESTARTSYS;
goto out2;
}
down(&globalfifo_devp->sem);
}
if(count>GLOBALFIFO_SIZE-globalfifo_devp->current_len)
count=GLOBALFIFO_SIZE-globalfifo_devp->current_len;

if(copy_from_user(globalfifo_devp->mem+globalfifo_devp->current_len,buf,count))
{
ret=-EFAULT;
goto out;
}
else
{
globalfifo_devp->current_len +=count;
printk(KERN_INFO"written %d bytes ,curren_len:%dn",count,globalfifo_devp->current_len);
wake_up_interruptible(&globalfifo_devp->r_wait);
ret=count;
}

out:up(&globalfifo_devp->sem);
out2:remove_wait_queue(&globalfifo_devp->w_wait,&wait);
     set_current_state(TASK_RUNNING);
     return ret;
}


static ssize_t globalfifo_read(struct file *filp,char __user *buf,size_t count,loff_t *ppos)
{
int ret;
DECLARE_WAITQUEUE(wait,current);
down(&globalfifo_devp->sem);
add_wait_queue(&globalfifo_devp->r_wait,&wait);
if(globalfifo_devp->current_len==0)
{
if(filp->f_flags & O_NONBLOCK)
{
ret = -EAGAIN;
goto out;
}
__set_current_state(TASK_INTERRUPTIBLE);
up(&globalfifo_devp->sem);
schedule();
if(signal_pending(current))
{
ret =-ERESTARTSYS;
goto out2;
}
down(&globalfifo_devp->sem);
}

if(count>globalfifo_devp->current_len)
count=globalfifo_devp->current_len;
if(copy_to_user(buf,globalfifo_devp->mem,count))
{
ret=-EFAULT;
goto out;
}
else
{
memcpy(globalfifo_devp->mem,globalfifo_devp->mem+count,globalfifo_devp->current_len-count);
globalfifo_devp->current_len-=count;
printk(KERN_INFO"read %d bytes,current_len:%dn",count,globalfifo_devp->current_len);
wake_up_interruptible(&globalfifo_devp->w_wait);
ret=count;
}
out:up(&globalfifo_devp->sem);
out2:remove_wait_queue(&globalfifo_devp->w_wait,&wait);
     return ret;
}


上面这段代码是读和写的,有几个问题
1.我执行cat /dev/globalfifo &后,然后echo "hello" > /dev/globalfifo,这个时候输出hello没错,但是不是程序应该直接结束吗?怎么好像可以再重复,好像没有while循环之类的把程序又跳到globalfifo_read的开头

2.DECLARE_WAITQUEUE(wait,current)的wait和current是在内核中就定义的吗?如果是那么read和write是否是在同一个等待队列里面?

3.当我执行cat /dev/globalfifo后,程序阻塞在哪条语句里面?

|
DECLARE_WAITQUEUE(wait,current)
这个应该是定义了一个名字叫做wait的 waitqueue 结构, current是内核的预定义的宏,表示当前进程task结构。

关键是 add_wait_queue(&globalfifo_devp->r_wait,&wait);
 这个把wait加到 一个全局的等待队列里面去了,所以你read和write函数都是等待的同一个&globalfifo_devp->r_wait 。


wake_up_interruptible(&globalfifo_devp->w_wait);
的时候就唤醒对方了。

当你执行 cat /dev/globalfifo的时候,因为这时globalfifo_devp->current_len==0)
 所以你执行到 schedule();的时候会把自己调度出去,也就是说停到这里了,一直等待对方的唤醒。 


当有写入的时候就执行的到wake_up在唤醒这个读进程了。


你看到的cat /dev/globalfifo  不会退出的原因是因为是,cat 会尝试读一直度到文件末尾。所以你第一个 globalfifo_read 返回hello时,cat认为你文件里面还有内容,会进行第二次globalfifo_read 的。你要设置 globalfifo_read 的返回值让cat知道已经读到文件末尾才行的。 不然第二次进来的时候有会断在那里。   你可以传个参数给cat让他只读指定的长度看看。

    
 
 

您可能感兴趣的文章:

  • 有关tasklet和工作队列的问题
  • 使用SYSTEM V队列,有关消息资源释放的问题
  • 请教有关linux驱动开发,按关机键关机时,驱动应作哪些结束工作?
  • 有关UNIX 的驱动的问题,是不是在系统中已经有了?
  • 请问一下有关LINUX内核的网卡驱动一个弱弱的问题
  • 有关2440 DMA驱动的问题
  • 有关消息驱动bean的问题!!!!高手救我!!!!
  • 各位高人,关于IDE的驱动程序,我看蒙了,谁能告诉我到底linux源文件中到底那些是跟IDE硬盘驱动有关的?
  • 有关SQLSERVER 2000的JDBC驱动的问题
  • 有关编译网卡驱动问题
  • 真心需要各位前辈指点,谢谢 有关LINUX USB驱动程序编写的一个问题
  • 有关ldd中字符驱动程序的scull_devices
  • 请教高手,有关字符设备驱动程序问题
  • 求助有关驱动的问题
  • 有关LINUX DMA驱动的问题
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • 有关linux平台的嵌入式开发工具
  • 有关ejb开发的问题?
  • 求助:有关GBA的开发软件
  • 有关在JBULIDER5中开发EJB的问题
  • 有关手机等的JAVA开发的书推荐点!谢谢!
  • NOSQL iis7站长之家
  • 有关电信软件开发的问题
  • 请教有关中国电信软件开发的问题
  • 有关Linux下开发程序--上万个线程问题。菜鸟问(来者有分,谢谢大家)
  • 有关学习unix开发的问题(100分),晚上结贴
  • 问个和硬件有关的问题:s3c2410开发板管脚
  • 请教:在FEDORA CORE 7下做B/S模式的WEB应用开发都需要掌握哪些与LINUX有关的基础知识?
  • 请教有经验的开发者一个有关实体bean的问题!
  • 有关代理服务器开发问题,最好提供原码!
  • ​有关Docker的八个令人难以置信的事实
  • 有关内码转换(跟HttpServletRequest有关)
  • 求有关png图像处理的libpng库的有关中文资料
  • 大家推荐一下有关LINUX7有关的网络编程的书。最好是比较全面的!比较经典的。
  • 求教有关smartupload的问题,有关就给分!!
  • 有关KDevelop-3.0.4-0.1.i386.rpm的有关软件包
  • 有关在sco unix5.0.4下有关网卡设置的问题(非常急,高分相送)
  • 有关snmp的一个很菜,但是困扰了我很久的问题,有关工作原理的,望大家赐教
  • 有关KDevelop编程的资料
  • 有关集群与数据同步
  • 请教有关英文简历方面的词句!
  • 有关报表打印(在JAVA,WEB下应用)急用!
  • 请各位大哥告知JAVA中消息机制的有关资料,拜托!
  • 有关cocoon的问题??
  • 有关jbuilder
  • 我想看看有关Linux和Unix的源码,有什么好的建议
  • 有关J2ME的帮助文档!


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3