首页 | 互联网 | IT动态 | IT培训 | Cisco | Windows | Linux | Java | .Net | Oracle | 软件测试 | C/C++ | 嵌入式开发 | 存储世界 | 服务器
网络设备 | IDC | 安全 | 求职招聘 | 数字网校 | 网页设计 | 平面设计 | 技术专题 | 电子书下载 | 教学视频 | 源码下载 | 搜索 | 博客 | 论坛
中国IT实验室Linux频道
Google
首页 入门 Linux编程 系统管理 网络管理 Linux认证 Unix/BSD Linux数据库 Linux集群 Linux手册 Linux下载 Ubuntu 论坛 专题 RSS
您现在的位置: 中国IT实验室 >> Linux >> 其他Unix >> 正文

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

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 |
       ----------------           -----

上一页  [1] [2] [3] 下一页

【责编:Yoyo】
中国IT教育
相关产品和培训
文章评论
 友情推荐链接
 专题推荐

 ·防范Linux病毒 打造没有病毒的乐土…
 ·Linux Shell编程实用指南…
 ·Linux日志分析与管理
 ·揭密Linux内存管理
 ·邮件服务Sendmail应用配置
 ·Linux 安全管理…
 ·Linux 下DNS服务器架设攻略…
 ·Linux 下的路由的配置与应用…
 ·专题:Apache实用手册
 ·全面剖析Linux文件系统
 今日更新
 认证培训
 频道精选
 Windows频道导航