阿里控股 面经

一面凉,甚至被面试官羞辱。

TCP拥塞控制,快速恢复,滑动窗口原理

C++锁的实现

/* 信号量结构 */
struct semaphore {
   uint8_t  value;
   struct   list waiters;
};

/* 锁结构 */
struct lock {
   struct   task_struct* holder;	    // 锁的持有者
   struct   semaphore semaphore;	    // 用二元信号量实现锁
   uint32_t holder_repeat_nr;		    // 锁的持有者重复申请锁的次数
};

#include "sync.h"
#include "list.h"
#include "global.h"
#include "debug.h"
#include "interrupt.h"

/* 初始化信号量 */
void sema_init(struct semaphore* psema, uint8_t value) {
   psema->value = value;       // 为信号量赋初值
   list_init(&psema->waiters); //初始化信号量的等待队列
}

/* 初始化锁plock */
void lock_init(struct lock* plock) {
   plock->holder = NULL;
   plock->holder_repeat_nr = 0;
   sema_init(&plock->semaphore, 1);  // 信号量初值为1
}

/* 信号量down操作 */
void sema_down(struct semaphore* psema) {
/* 关中断来保证原子操作 */
   enum intr_status old_status = intr_disable();
   while(psema->value == 0) {	// 若value为0,表示已经被别人持有
      ASSERT(!elem_find(&psema->waiters, &running_thread()->general_tag));
      /* 当前线程不应该已在信号量的waiters队列中 */
      if (elem_find(&psema->waiters, &running_thread()->general_tag)) {
	 PANIC("sema_down: thread blocked has been in waiters_list\n");
      }
/* 若信号量的值等于0,则当前线程把自己加入该锁的等待队列,然后阻塞自己 */
      list_append(&psema->waiters, &running_thread()->general_tag); 
      thread_block(TASK_BLOCKED);    // 阻塞线程,直到被唤醒
   }
/* 若value为1或被唤醒后,会执行下面的代码,也就是获得了锁。*/
   psema->value--;
   ASSERT(psema->value == 0);	    
/* 恢复之前的中断状态 */
   intr_set_status(old_status);
}

/* 信号量的up操作 */
void sema_up(struct semaphore* psema) {
/* 关中断,保证原子操作 */
   enum intr_status old_status = intr_disable();
   ASSERT(psema->value == 0);	    
   if (!list_empty(&psema->waiters)) {
      struct task_struct* thread_blocked = elem2entry(struct task_struct, general_tag, list_pop(&psema->waiters));
      thread_unblock(thread_blocked);
   }
   psema->value++;
   ASSERT(psema->value == 1);	    
/* 恢复之前的中断状态 */
   intr_set_status(old_status);
}

/* 获取锁plock */
void lock_acquire(struct lock* plock) {
/* 排除曾经自己已经持有锁但还未将其释放的情况。*/
   if (plock->holder != running_thread()) { 
      sema_down(&plock->semaphore);    // 对信号量P操作,原子操作
      plock->holder = running_thread();
      ASSERT(plock->holder_repeat_nr == 0);
      plock->holder_repeat_nr = 1;
   } else {
      plock->holder_repeat_nr++;
   }
}

/* 释放锁plock */
void lock_release(struct lock* plock) {
   ASSERT(plock->holder == running_thread());
   if (plock->holder_repeat_nr > 1) {
      plock->holder_repeat_nr--;
      return;
   }
   ASSERT(plock->holder_repeat_nr == 1);

   plock->holder = NULL;	   // 把锁的持有者置空放在V操作之前
   plock->holder_repeat_nr = 0;
   sema_up(&plock->semaphore);	   // 信号量的V操作,也是原子操作
}


手撕-最多有多少个箱子

sort后再动态规划

相关推荐

  1. 阿里控股

    2023-12-28 21:16:06       40 阅读
  2. 阿里巴巴实习

    2023-12-28 21:16:06       21 阅读
  3. python

    2023-12-28 21:16:06       36 阅读
  4. SpringCloud

    2023-12-28 21:16:06       26 阅读
  5. 复习

    2023-12-28 21:16:06       30 阅读
  6. C++

    2023-12-28 21:16:06       34 阅读

最近更新

  1. TCP协议是安全的吗?

    2023-12-28 21:16:06       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-28 21:16:06       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-28 21:16:06       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-28 21:16:06       20 阅读

热门阅读

  1. 快速排序回顾及相关题型

    2023-12-28 21:16:06       40 阅读
  2. 72 DFS解决目标和问题

    2023-12-28 21:16:06       34 阅读
  3. 进程

    进程

    2023-12-28 21:16:06      33 阅读
  4. nginx部署前端项目总结

    2023-12-28 21:16:06       44 阅读
  5. C++_静态成员变量介绍

    2023-12-28 21:16:06       33 阅读
  6. MOS和三极管

    2023-12-28 21:16:06       39 阅读
  7. Go语言并发编程:Goroutines和Channels的详细指南

    2023-12-28 21:16:06       46 阅读
  8. 应对微信小程序用户流失率的有效策略

    2023-12-28 21:16:06       35 阅读
  9. js 事件处理(addEventListener() 、removeEventListener())

    2023-12-28 21:16:06       36 阅读
  10. 浅谈Linux的OOM Killer机制

    2023-12-28 21:16:06       36 阅读
  11. nginx配置后不生效的问题

    2023-12-28 21:16:06       39 阅读
  12. IP地址学习(一)

    2023-12-28 21:16:06       39 阅读