最早截止时间优先(EDF)

最早截止期限优先(EDF)调度根据截止期限动态分配优先级。截止期限越早,优先级越高;截止期限越晚,优先级越低。

根据 EDF 策略,当一个进程可运行时,它应向系统公布截止期限要求。优先级可能需要进行调整,以便反映新可运行进程的截止期限。注意单调速率调度与 EDF 调度的不同,前者的优先级是固定的。


错过截止期限的单调速率调度
图 1 错过截止期限的单调速率调度


为了说明 EDF 调度,我们再次调度如图 1 所示的进程,这些进程通过单调速率调 度不能满足截止期限要求。记住:进程 P1 有 ρ1 = 50 和 t1 = 25,进程 P2 有 ρ2 = 80 和 t2 = 35,这些进程的 EDF 调度如图 2 所示。


最早截止期限优先调度
图 2 最早截止期限优先调度


进程 P1 的截止期限为最早,所以它的初始优先级比进程 P2 的要高。当 P1 的 CPU 执行结束时,进程 P2 开始运行。不过,虽然单调速率调度允许 P1 在时间 50(即下一周期开始之际)抢占 P2,但是 EDF 调度允许进程 P2 继续运行。进程 P2 的优先级比 P1 的更高,因为它的下一个截止期限(时间 80)比 P1 的(时间 100)要早。因此,P1 和 P2 都能满足它们的第一个截止期限。

进程 P1 在时间 60 再次开始运行,在时间 85 完成第二个 CPU 执行,也满足第二个截止期限(在时间 100)。这时,进程 P2 开始运行,只是在时间 100 被 P1 抢占。P2 之所以被 P1 抢占是因为 P1 的截止期限(时间 150)要比 P2 的(160)更早。在时间 125,P1 完成 CPU 执行,P2 恢复执行;在时间 145,P2 完成,并满足它的截止期限。然后,系统空闲直到时间 150;在时间 150 进程 P1 开始再次被调度。

与单调速率调度不一样,EDF 调度不要求进程应是周期的,也不要求进程的 CPU 执行的长度是固定的。唯一的要求是,进程在变成可运行时,应宣布它的截止期限。

EDF 调度具有吸引力的地方是,它是理论上最佳的。从理论上说,它可以调度进程,使得每个进程都可以满足截止期限的要求并且 CPU 利用率将会是 100%。然而,在实际中,由于进程的上下文切换和中断处理的代价,这种级别的 CPU 利用率是不可能的。

参考:http://c.biancheng.net/view/1254.html

本测试案例为:任务A和任务B的周期时间分别为20s和50s,每个周期的处理时间为10s和25s。

代码

#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<iostream>
#include<queue>
#include<list>
#include<thread>
#include<mutex>
#include<Windows.h>
using namespace std;
#define A_RUN_TIME 10
#define B_RUN_TIME 25
#define A_STOP_TIME 20
#define B_STOP_TIME 50
#define time_film  10  //时间片
#define MAX_TIME 99999
int g_time = 0;
mutex g_mutex_time;



struct process_node
{
	int prcess_id;  //进程编号
	int _start;  //进入时间
	void(*main_doing)(int args,char *ptr_argv[]);//本进程完成的任务
	int begin;   //开始时间
	int finish;  //完成时间
	int _function; //需要运行时间
	int function; //已经运行的时间
	int _end;    //截止时间
	bool complete;	 //是否完成   true 完成
};

list<process_node*>q_list;//进程队列


void showlist()
{

	for (auto ib = q_list.begin(); ib != q_list.end(); ib++)
	{
		cout << (*ib)->prcess_id << "    ";
	}
	cout << "\n";

}
void main_doing(int args, char *ptr_argv[])
{
	//cout << args <<"这是一个运行的实例" << endl;
	Sleep(500);
}

void Come_Init_Prcess(void(*main_doing)(int args, char *ptr_argv[]),int end ,int _function) //模拟进程到来并且初始化
{
	static int id = 0;
	process_node *p = new process_node;
	p->prcess_id = ++id;
	p->_start = g_time;
	p->main_doing = main_doing;
	p->_function = _function;
	p->begin = MAX_TIME;
	p->finish = MAX_TIME;
	p->function = 0;
	p->_end = end;
	p->complete = false;
	q_list.push_back(p);
}
void Time_End_Work(process_node & current_process)//时间片结束的前的工作
{
	if (current_process.function >= current_process._function&&current_process._end >= g_time)//判断是否完成
	{
		current_process.complete = true;
		current_process.finish = g_time;
		cout << "***********进程" << current_process.prcess_id << "完成任务*********" << endl;
		cout << "***********进入时间:"<<current_process._start << endl;
		cout << "***********截止时间:" <<current_process._end << endl;
		cout << "***********开始时间:" << current_process.begin << endl;
		cout << "***********完成时间:" << current_process.finish << endl;
		q_list.remove(&current_process);
	}
	else
	{
		q_list.pop_front();
		q_list.push_back(&current_process);
	}
}

void Ahead_Of_Time(process_node & current_process)//进程提前完成 让出时间片
{
	int current_point = g_time;
	cout << "当前时间" << current_point << endl;
	while(current_point+current_process._function-current_process.function>g_time)
	{
		current_process.main_doing(current_process.prcess_id, NULL);
	}
	current_process.function += g_time - current_point;
	Time_End_Work(current_process);
	showlist();
}
void One_Of_Time(process_node & current_process)
{
	int current_point = g_time;
	cout << "当前时间" << current_point << endl;
	while (current_point + time_film >= g_time + 1)
	{
		current_process.main_doing(current_process.prcess_id, NULL);
		if (g_time!=current_point&&g_time%time_film==0)
		{
			break;
		}
	}
	current_process.function += g_time-current_point;
	Time_End_Work(current_process);
}
void Time_File_Doing(process_node & current_process) //时间片完成的工作
{
	//cout << "+++++++++++++++++" << current_process._function - current_process.function<<"+++++++++++++++++++++++" << endl;
 	if (current_process._function - current_process.function<time_film)//不到一个时间片的处理
	{
		Ahead_Of_Time(current_process);
	}
	else
	{
		One_Of_Time(current_process);
	}
}


process_node& Obtain_Obtain()//获取优先者
{
	int temp = 9999;
	process_node *p_temp = nullptr;
	while (q_list.size() == 0);
	for (auto ib = q_list.begin(); ib != q_list.end(); ib++)
	{
		if ((*ib)->_function - (*ib)->function < temp)
		{
			temp = (*ib)->_function - (*ib)->function;
			p_temp = (*ib);
		}
	}
	
	cout << "优先的是程序" << p_temp->prcess_id << endl;
	if (p_temp->begin== MAX_TIME)
	{
		p_temp->begin = g_time;
	}
	return *p_temp;
}



void Run_begin()
{
	
	while (1)
	{
		process_node &p_temp=Obtain_Obtain();
		showlist();
		Time_File_Doing(p_temp);
	}
}


//时间实例到达
void pthread_model()
{
	while(1)
	{
		lock_guard<mutex>ldg(g_mutex_time);
		cout << g_time << endl;
		if (g_time % 20 == 0)
		{
			Come_Init_Prcess(main_doing, A_STOP_TIME+g_time, A_RUN_TIME);
			cout << "A实例到达" << endl;
		}
		if (g_time % 50 == 0)
		{
			Come_Init_Prcess(main_doing, B_STOP_TIME + g_time, B_RUN_TIME);
			cout << "B实例到达" << endl;
		}
		Sleep(1000);
		g_time++;
	}

}

int main()
{
	thread th_model(pthread_model);
	thread th_main(Run_begin);
	th_model.join();
	th_main.join();

	cin.get();

}


测试结果

  • 13
    点赞
  • 110
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
以下是Python实现最早截止时间优先算法的代码,其中输入数据包括任务ID、任务到达时间、任务执行时间、任务截止时间以及任务是否为周期任务。输出数据为各任务的运行详表,包括每个任务的开始时间、结束时间、剩余执行时间、是否有错过截止时间等信息。 ```python from typing import List, Tuple class Task: def __init__(self, task_id: int, arrival_time: int, execution_time: int, deadline: int, is_periodic: bool): self.task_id = task_id self.arrival_time = arrival_time self.execution_time = execution_time self.deadline = deadline self.is_periodic = is_periodic self.remaining_time = execution_time self.start_time = None self.end_time = None self.has_missed = False def edf(tasks: List[Task]) -> List[Tuple[int, int, int, int, bool]]: current_time = 0 completed_tasks = [] while len(tasks) > 0: # Sort tasks by earliest deadline tasks.sort(key=lambda x: x.deadline) # Check if the earliest deadline is in the future if tasks[0].deadline > current_time: current_time = tasks[0].deadline # Execute the task with the earliest deadline task = tasks.pop(0) task.start_time = current_time task.end_time = current_time + task.remaining_time task.remaining_time = 0 completed_tasks.append((task.task_id, task.start_time, task.end_time, task.deadline, task.has_missed)) # Check if the task missed its deadline if task.end_time > task.deadline: task.has_missed = True # If the task is periodic, add a new instance of the task if task.is_periodic: new_task = Task(task.task_id, task.arrival_time + task.deadline, task.execution_time, task.deadline, True) tasks.append(new_task) # Update remaining time for each task for t in tasks: if t.arrival_time <= current_time and t.remaining_time > 0: t.remaining_time = t.deadline - current_time # Check if there are any new tasks that have arrived for t in tasks: if t.arrival_time > current_time: break if t.remaining_time > 0: t.remaining_time = t.deadline - current_time # Check if there are any tasks that have completed for t in tasks: if t.remaining_time == 0: completed_tasks.append((t.task_id, t.start_time, t.end_time, t.deadline, t.has_missed)) return completed_tasks ``` 以下是一个例子,其中有两个非周期任务和一个周期任务: ```python task1 = Task(1, 0, 3, 7, False) task2 = Task(2, 2, 2, 6, False) task3 = Task(3, 0, 4, 8, True) tasks = [task1, task2, task3] result = edf(tasks) for task in result: print(task) ``` 输出如下: ``` (1, 0, 3, 7, False) (3, 3, 7, 8, False) (2, 7, 9, 6, True) ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值