免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3543 | 回复: 10

关于等待队列 [复制链接]

论坛徽章:
0
发表于 2009-01-10 23:43 |显示全部楼层
关于等待队列,关于等待队列的具体执行过程大家来讨论一下,实例代码:
v2.6.11/net/irda/af_irda.c#L832
832static int irda_accept(struct socket *sock, struct socket *newsock, int flags)
833{
834        ...
875        if (skb == NULL) {
876                int ret = 0;
877                DECLARE_WAITQUEUE(waitq, current);
878
879                /* Non blocking operation */
880                if (flags & O_NONBLOCK)
881                        return -EWOULDBLOCK;
882
883                /* The following code is a cut'n'paste of the
884                 * wait_event_interruptible() macro.
885                 * We don't us the macro because the condition has
886                 * side effects : we want to make sure that only one
887                 * skb get dequeued - Jean II */

888                add_wait_queue(sk->sk_sleep, &waitq);
889                for (;;) {
890                        set_current_state(TASK_INTERRUPTIBLE);
891                        skb = skb_dequeue(&sk->sk_receive_queue);
892                        if (skb != NULL)
893                                break;
894                        if (!signal_pending(current)) {
895                                schedule();
896                                continue;
897                        }
898                        ret = -ERESTARTSYS;
899                        break;
900                }
901                current->state = TASK_RUNNING;
902                remove_wait_queue(sk->sk_sleep, &waitq);
903                if(ret)
904                        return -ERESTARTSYS;
905        }
              ...

论坛徽章:
0
发表于 2009-01-11 00:57 |显示全部楼层
讨论什么?

论坛徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
发表于 2009-01-11 09:13 |显示全部楼层
这段代码的大致意思是当skb为NULL时,如果不是O_NONBLOCK(非阻塞)型的,就把自己加入等待队列,等待事件的发生(也可以说是资源可获取)。
当被唤醒后:skb = skb_dequeue(&sk->sk_receive_queue);
就是去读取skb,然后做一些检查,看是否是信号把自己唤醒的,等待的资源是否真的获得等。
推出for循环以后,就把自己的状态置为TASK_RUNNING,并把自己从等待队列中移出。

关于等待队列的详细描述,LDD和ULK都有比较详细的描述。

论坛徽章:
0
发表于 2009-01-12 16:10 |显示全部楼层

回复 #3 dreamice 的帖子

嗯,dreamice解释的比较清楚

论坛徽章:
0
发表于 2009-01-12 17:29 |显示全部楼层
我帮lz问两个问题吧?

  1. for (;;) {
  2. 890                        set_current_state(TASK_INTERRUPTIBLE);
  3. 891                        skb = skb_dequeue(&sk->sk_receive_queue);
  4. 892                        if (skb != NULL)
  5. 893                                break;
  6. 894                        if (!signal_pending(current)) {
  7. 895                                schedule();
  8. 896                                continue;
  9. 897                        }
  10. 898                        ret = -ERESTARTSYS;
  11. 899                        break;
  12. 900                }
复制代码


1. 当skb为NULL, 且没有signal pending的时候, 则重新schedule.
问题:为什么schedule之后, 不尝试从sk->receive_queue中取数据, 然后如果是null再continue呢?

例如:
当它schedule到另外一个task后,突然接收到一个报文存到recevice_queue中, 然后从schedule返回后, 如果按照现在的写法, 它会执行continue的动作.

2. skb为NULL, 且有signal pending为何要从新执行一次sys_call, 是不是在执行irda_accept之前会处理信号的handler(没看代码, 想确认下)

论坛徽章:
0
发表于 2009-01-12 17:31 |显示全部楼层
对于问题1, 还有一种情况: 当切到另外一个任何后 只收一个报文(以后不会收到任何报文), 那么它schedule返回 按照我能力的理解它会sleep forever.

论坛徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
发表于 2009-01-13 10:16 |显示全部楼层
问题1:如果continue的话,你想想这种情况——本身这个进程也同时在等待一个信号,但不知道是因为信号到了还是资源可用了,信号就是不能忽略的。
问题2:信号可以说是对一个进程的中断,他也是异步的。

论坛徽章:
0
发表于 2009-01-13 10:36 |显示全部楼层
原帖由 dreamice 于 2009-1-13 10:16 发表
问题1:如果continue的话,你想想这种情况——本身这个进程也同时在等待一个信号,但不知道是因为信号到了还是资源可用了,信号就是不能忽略的。
问题2:信号可以说是对一个进程的中断,他也是异步的。



对于你问题1的描述, 我这样理解:

a. 信号不可以丢掉.
b. 如果schdule之后, continue之前, 我直接检查资源然后break, 那么这个信号就被丢掉了.

是不是这样?


另外, 如果在schdule之后, continue之前, 进程收到一个报文(这个时候应该回被data_ready唤醒吧), 但进程continue继续sleep, 那么
这个唤醒信号会不会丢失.

论坛徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
发表于 2009-01-13 10:57 |显示全部楼层

回复 #8 Arthur_ 的帖子

不是不可以丢掉,随意丢掉信号的后果有时候是不堪设想的,所以有可靠信号与不可靠信号之分。信号可以和中断类比,就像不能随意丢掉一个终端一样。

论坛徽章:
3
戌狗
日期:2014-09-10 17:07:162015年辞旧岁徽章
日期:2015-03-03 16:54:15wusuopu
日期:2016-06-17 17:43:45
发表于 2009-01-13 15:44 |显示全部楼层
原帖由 dreamice 于 2009-1-13 10:57 发表
不是不可以丢掉,随意丢掉信号的后果有时候是不堪设想的,所以有可靠信号与不可靠信号之分。信号可以和中断类比,就像不能随意丢掉一个终端一样。

学习
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP