科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网网络频道UNIX操作系统的加锁解锁:等待事件及唤醒

UNIX操作系统的加锁解锁:等待事件及唤醒

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

加锁和解锁的基本思想是,当某个进程进入临界区,它将持有一个某种类型的锁(UNIX里一般来说是semaphore,Linux里一般是信号量和原子量或者spinlock)。

来源:chinaitlab 2007年12月27日

关键字: unix 系统安全

  • 评论
  • 分享微博
  • 分享邮件

在本页阅读全文(共3页)

void wakeup(地址(事件))

{
    禁用所有的中断;
    根据地址(事件)查找睡眠进程队列;
    for(每个在该事件上睡眠的进程)
    {
       将该进程从哈希队列中移出;
       设置状态为就绪;
       将该进程放入调度链表中;
       清除进程表中的睡眠地址(事件);
       if(进程不在内存中)
       {
          唤醒swapper进程;
       }
       else if(唤醒的进程更适合运行)
       {
          设置调度标志;
       }
    }
    恢复中断;
      }

在wakeup调用之后,被唤醒的进程并不是马上投入运行,而是让其适合运行,等到下次调度该进程才有机会运行(也可能不会运行)。

代码示例:

由于没能找到UNIX的源码,因此用Linux的源代码替代。上述伪代码已经是比较简单的处理。Linux 0.01则更简单。

//Linux 0.01的实现:
//不可中断睡眠
void sleep_on(struct task_struct **p)
{
    struct task_struct *tmp;
    if (!p)
        return;
    if (current == &(init_task.task))  //current宏用来获取当前运行进程的task_struct
        panic("task[0] trying to sleep");
    tmp = *p;                          //将已经在睡眠的进程p2保存到tmp
    *p = current;                   //将当前进程p1保存到睡眠进程队列中(实际上只有一个)
    current->state = TASK_UNINTERRUPTIBLE; //p1状态设置为不可中断的睡眠
    schedule();                        //上下文切换,执行其他进程
    //p1被唤醒后回到此处
    if (tmp)
        tmp->state=0;       //将p2的状态设置为运行,等待调度
}
//可中断睡眠
void interruptible_sleep_on(struct task_struct **p)
{
    struct task_struct *tmp;
    if (!p)
        return;
    if (current == &(init_task.task))
        panic("task[0] trying to sleep");
    tmp=*p;        //正在等待的进程p2保存到tmp
    *p=current;    //将当前进程p1保存到睡眠进程队列中
repeat:    current->state = TASK_INTERRUPTIBLE; //将p1状态设置为可中断睡眠
    schedule();                                 //上下文切换
    if (*p && *p != current) {   //p2睡眠被中断
        (**p).state=0;//p1设置为运行态
        goto repeat;  //回到repeat,继续让p2睡眠
    }
    *p=NULL;
    if (tmp)
        tmp->state=0;       //将p2的状态设置为运行态,等待调度
      }

这两个函数比较难以理解,主要是在最后两条语句。在schedule()之前,切换的是当前进程的上下文,但是,切换回来之后,却是将原先正在睡眠的进程置为就绪态。在执行schedule()之前,各指针如下图所示(不好意思,不会粘贴图片):

---
| p |
 ---
 ||
 \/
 ----   Step 3   ---------
| *p |--------->| current |
 ----            ---------
   |
   X   Step 1
   |
   \/
 ----------------   Step 2  -----
|  Wait Process  |<--------| tmp |
       ----------------           -----
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章