查看: 5350| 回复: 5
跳转到指定楼层
上一主题 下一主题
收起左侧

求问一道关于多线程queue的面试题

全局:

注册一亩三分地论坛,查看更多干货!

您需要 登录 才可以下载或查看附件。没有帐号?注册账号

x
本帖最后由 Ulu2005 于 2015-3-18 07:03 编辑

设计一个task dispatching system,里面有一个task queue和两个function。并且这个queue的所有operation是atomic的。
1. trigger() 这个function运行并清空task queue中所有的tasks。
2. addTask(task) 在trigger之前把task加入task queue,在trigger之后直接运行task。

在mitbbs有一个被说不是最优解的解法,使用了一个全局布尔变量来判断queue是否已经被trigger。
  1. trigger(){
  2.   aquire(mutex_a);   
  3.   a = true;      
  4.   dispatch all tasks in the queue;
  5.   head = null;
  6.   tail = null;
  7.   release(mutex_a);
  8. }
复制代码
  1. addtask(){
  2.      aquire(mutex_a);
  3.      if(a)
  4.           dispatch the task;
  5.      else{
  6.           if(head == null){
  7.                head = task;
  8.                tail = task;
  9.           } else{
  10.                tail.next = task;
  11.                tail = task;
  12.           }
  13.      }
  14.      release(mutex_a);
  15. }
复制代码
我个人觉得queue是否被trigger的区别在于这个queue是否为空,因为queue被trigger后整个queue就空了,没有必要去增加一个全局变量。而且addTask()和trigger()应该是不冲突的,trigger()总是取queue最前面的一个task来run,而新的task总被加到queue的末尾,上面这样加锁system性能会很差。
  1. trigger() {
  2.     while(!queue.isEmpty()) {
  3.         lock(&m);
  4.         get & remove task from queue;
  5.         run task;
  6.         unlock(&m);
  7.     }
  8. }

  9. addTask(task) {
  10.     if (queue.isEmpty()) {
  11.         lock(&m);
  12.         run task;
  13.         unlock(&m);
  14.     } else {
  15.         queue.add(task);
  16.     }
  17. }
复制代码
以上是我的写法,这样加锁可以使queue不为空时,能够同时trigger和addTask。而且可以保证queue里的最后一个task被取出来后,总是能够在addTask(task)的task之前运行。
但是这样写有个bug就是当queue为空,多个addTask(task)被call,task永远没有办法被add进queue,会处于顺序执行状态。持有锁的那个addTask会run task。这样queue就失去了存在的意义。不知道我的写法应该怎么改进,求指导。



上一篇:请问大家怎么准备behavior question的
下一篇:leetcode 题目 time limit exceeded
🔗
Urumic 2016-6-9 13:49:56 | 只看该作者
全局:
请问这是一个环形的queue吗。为什么head = task; tail = task;
回复

使用道具 举报

🔗
lea82 2016-6-10 07:56:19 | 只看该作者
全局:

void register(Callback cb) {
  m.acquire();. 涓
回复

使用道具 举报

🔗
不是老子 2016-7-22 06:51:59 | 只看该作者
全局:
感觉还是要加全局变量的, 因为在最开始的时候,queue为空,trigger也没被调用,这个时候仅仅是用queue是否为空来判断就不是很好了。
回复

使用道具 举报

全局:
mitbbs那个解法是默认trigger仅发生一次的,可是task dispatch system逻辑上应该是个循环吧,应该还有reset操作的
回复

使用道具 举报

全局:
有两个问题需要clearify下,
1.是否要实现多次trigger,如果只一次那mitbbs那个答案应该是没问题
2.我的理解应该是多次call,本质上就是生产者消费者模型,那么多个addtask的情况是否需要保证公平性?不需要的话,阻赛队列即可;需要的话需要自己加可重入锁
欢迎讨论~
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

>
快速回复 返回顶部 返回列表