`
hongbochen1223
  • 浏览: 43997 次
文章分类
社区版块
存档分类
最新评论

进程调度(三)

阅读更多

(一)睡眠和唤醒

休眠(被阻塞)的进程处于一个特殊的不可执行状态。无论什么原因,导致进程进入休眠状态,内核的操作都是相同的:进程把自己标志成休眠状态,从可执行红黑树中移出,放入等待队列,然后调用schedule()选择和执行一个其他进程。唤醒的过程正好相反,进程把自己标志成可运行状态,然后再从等待队列中移到可执行红黑树中。

1:等待队列
休眠通过等待队列进程处理,等待队列是由等待某些事件的发生的进程组成的简单链表。内核使用wake_queue_head_t来代表等待队列。等待队列可以通过DECLARE_WAITQUEUE静态创建,也可以由init_wakequeue_head()动态创建。

进程通过下面几个步骤,将自己加入到一个等待队列中:

​1:调用宏DEFINE_WAIT()创建一个等待队列的项。    ​
​2:调用add_wait_queue()将自己加入到队列中。该队列会在进程等待的条件满足时唤醒他。当然,这需要编写代码,当事件满足时,对等待队列执行wake_up()操作。
​3:调用prepare_to_wait()方法将进程的状态变更为TASK_INTERRUPTIBLE或TASK_UNINTERRUPTIBLE,而且该函数如果有必要的话会将进程加入到等待队列,这是在接下来的循环遍历中所需要的。

​4:如果状态被设置为TASK_INTERRUPTIBLE,则信号唤醒进程,这就是所谓的伪唤醒(唤醒不是因为事件的发生),因此检查并处理信号。
​5:当进程被唤醒的时候,他会再次检查条件是否为真。如果是,他就会退出循环;如果不是,他会再次调用schedule()并一直重复这步操作。
​6:当条件满足后,进程将自己设置为TASK_RUNNING并调用finish_wait()函数把自己移出等待队列。

现在我们考虑一下是否会发生竞争的现象:当进程在开始休眠之前条件就已经达成了,那么循环会退出,进程不会再错误的进入睡眠的倾向。注意:进程在进入循环之前,需要完成一些其他的任务:包括调用schedule()之前需要释放掉锁,而在这以后再重新获取他们,或者相应其他事件。

函数inotify_read(),位于fs/notify/inotify/inotify_user.c文件中,负责从通知文件描述符中读取信息,他的实现是等待队列的一个比较典型的用法。

下面我们通过这个函数来体会一下,进程进入休眠状态的过程:

static ssize_t inotify_read(struct file *file, char __user *buf,
                size_t count, loff_t *pos)
{
    struct fsnotify_group *group;
    struct fsnotify_event *kevent;
    char __user *start;
    int ret;
    DEFINE_WAIT(wait);
    start = buf;
    group = file->private_data;
    while (1) {
        prepare_to_wait(&group->notification_waitq, &wait, TASK_INTERRUPTIBLE);
        mutex_lock(&group->notification_mutex);
        kevent = get_one_event(group, count);
        mutex_unlock(&group->notification_mutex);
        if (kevent) {
            ret = PTR_ERR(kevent);
            if (IS_ERR(kevent))
                break;
            ret = copy_event_to_user(group, kevent, buf);
            fsnotify_put_event(kevent);
            if (ret < 0)
                break;
            buf += ret;
            count -= ret;
            continue;
        }
        ret = -EAGAIN;
        if (file->f_flags & O_NONBLOCK)
            break;
        ret = -EINTR;
        if (signal_pending(current))
            break;
        if (start != buf)
            break;
        schedule();
    }
    finish_wait(&group->notification_waitq, &wait);
    if (start != buf && ret != -EFAULT)
        ret = buf - start;
    return ret;
}

2:唤醒

唤醒操作通过函数wake_up()进行,他会唤醒指定的等待队列上的所有进程。他调用函数try_to_wake_up(),该函数负责将进程设置为TASK_RUNNING状态,调用enqueue_task()将此进程放入红黑树中,如果被唤醒的进程比当前正在运行的进程的优先级高,还要设置need_resched标志。

<script type="text/javascript"> $(function () { $('pre.prettyprint code').each(function () { var lines = $(this).text().split('\n').length; var $numbering = $('<ul/>').addClass('pre-numbering').hide(); $(this).addClass('has-numbering').parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($('<li/>').text(i)); }; $numbering.fadeIn(1700); }); }); </script>

版权声明:本文为博主原创文章,未经博主允许不得转载。

分享到:
评论

相关推荐

    进程调度程序模拟 进程调度程序模拟 进程调度程序模拟

    进程调度程序模拟 进程调度程序模拟 进程调度程序模拟 进程调度程序模拟 进程调度程序模拟 进程调度程序模拟

    操作系统实验三 进程调度算法实验

    操作系统实验三:进程调度算法实验报告。加深对进程调度概念的理解,体验进程调度机制的功能,了解Linux系统中进程调度策略的使用方法。 练习进程调度算法的编程和调试技术。三种调度方法:  1,SCHED_OTHER 分时...

    单处理器系统的进程调度

    实验二 单处理器系统的进程调度 1.实验目的 加深对进程概念的理解,明确进程和程序的区别; 深入了解系统如何组织进程、创建进程; 进一步认识如何实现处理器调度。 2.实验预备知识 进程的概念; 进程的组织方式...

    进程调度论文进程调度论文 part2

    进程调度论文进程调度论文进程调度论文进程调度论文进程调度论文进程调度论文进程调度论文进程调度论文进程调度论文

    实验一 进程调度实验报告

    进程调度课程设计 给需要的人 呵呵 实验一 进程调度实验 一、实验目的 通过对进程调度算法的模拟加深对进程概念和进程调度算法的理解。 二、实验要求 编写程序实现对5个进程的调度模拟,要求至少采用两种不同的...

    进程调度的设计与分析实验报告

    综合应用下列知识点设计并实现操作系统的进程调度:邻接表,布尔数组,非阻塞输入,图形用户界面GUI,进程控制块,进程状态转换,多级反馈队列进程调度算法。 2、 加深理解操作系统进程调度的过程。 3、 加深理解...

    操作系统进程调度实验

    进程调度模拟程序:假设有10个进程需要在CPU上执行,分别用: 先进先出调度算法; 基于优先数的调度算法; 最短执行时间调度算法 确定这10个进程在CPU上的执行过程。要求每次进程调度时在屏幕上显示: 当前...

    操作系统进程调度算法 c语言实现

    实现进程调度算法,具有后备序列的调度 题目:设计一个有 N个进程共行的进程调度程序。 进程调度算法:采用最高优先数优先的调度算法(即把处理机分配给优先数最高的进程)和先来先服务算法。 每个进程有一个进程...

    C#进程调度模拟算法

    C#进程调度模拟算法C#进程调度模拟算法C#进程调度模拟算法

    进程调度算法的设计

    进程调度算法的设计 设计要求: ①设计进程控制块PCB表结构,分别适用于优先数调度算法和循环轮转调度算法。 ②建立进程就绪队列。对两种不同算法编制入链子程序。 ③编制两种进程调度算法:1)优先数调度;2)循环...

    设计一个有 N个进程共行的进程调度程序

    1、进程调度算法:采用动态最高优先数优先的调度算法(即把处理机分配给优先数最高的进程)。 2、每个进程有一个进程控制块( PCB)表示。进程控制块可以包含如下信息: 进程名---进程标示数 ID 优先数 PRIORITY ...

    操作系统实验一: 进程调度

    实验1 进程调度(2学时) 一、实验目的 通过实验加强对进程调度算法的理解和掌握。 二、实验内容 编写程序实现基于优先级的时间片轮转调度算法。 三、实验要求 1、假定系统有5个进程,每个进程用一个进程...

    C++进程优先级调度进程优先级调度进程优先级调度

    C++进程优先级调度进程优先级调度进程优先级调度C++进程优先级调度进程优先级调度进程优先级调度

    操作系统实验报告三——进程调度 进程调度实验原理

    操作系统 实验报告三 进程调度 进程调度实验 进程调度原理

    进程调度模拟程序 图形演示

    这就要求系统能按某种算法,动态地把处理机分配给就绪队列中的一个进程,使之运行,分配处理机的任务是由进程调度程序完成的。一个进程被创建后,系统为了便于对进程进行管理,将系统中的所有进程按其状态,将其组织...

    【C语言源代码】 操作系统-短进程优先-进程调度算法

    C语言实现:短进程优先-进程调度算法 1. 采用“短进程优先”调度算法对五个进程进行调度。每个进程有一个进程控制块( PCB)表示。进程控制块可以包含如下信息:进程名、到达时间、需要运行时间、已用CPU时间、进程...

    进程调度实验 用高级语言编写和调试一个进程调度程序,以加深对进程的概念及进程调度算法的理解。

    每个进程有一个进程控制块(PCB)表示。进程控制块可以包含如下信息:进程名、优先数、到达时间、需要运行时间、已用CPU时间、...每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的PCB,以便进行检查。

    操作系统进程调度C++代码实现

    目的: 在进程控制、请求分页存储器管理、设备管理基础上 实现按先来...5.调度时应适当输出调度过程中各进程状态队列的变化情况以及进程的已执行时 间、还需服务时间(针对时间片轮转算法)。 6.完成银行家算法的实现。

    进程调度设计与实现

    1、 综合应用下列知识点设计并实现操作系统的进程调度:邻接表,布尔数组,非阻塞输入,图形用户界面GUI,进程控制块,进程状态转换,多级反馈队列进程调度算法。 2、 加深理解操作系统进程调度的过程。 3、 加深...

    使用动态优先权的进程调度算法的模拟

    通过动态优先权算法的模拟加深对进程概念和进程调度过程的理解。 2、实验内容 (1)用C语言来实现对N个进程采用动态优先算法的进程调度; (2)每个用来标识进程的进程控制块 PCB用结构来描述,包括以下字段: 进程...

Global site tag (gtag.js) - Google Analytics