📅  最后修改于: 2023-12-03 15:28:38.870000             🧑  作者: Mango
本题为2021年计算机科学门(GATE CS)考试中的一道题目,是一道数据结构与算法相关的问题。该题目有一定难度,需要有一定算法基础和思维能力。
假设有 $N$ 个进程需要占用一个公共资源,资源同时只能被一个进程占用。如果有多个进程同时请求资源,则他们按照序号依次排队执行,即第一个进程先执行,直到占用资源的进程退出后,紧接着执行下一个进程。现在有 $M$ 次请求资源的操作,对于每次请求,给定该进程的序号 $i$,请求类型(请求或者释放)和时间戳 $t$,请编写代码实现上述机制。
第一行包含两个正整数 $N$ 和 $M$,分别表示进程数量和操作次数。
接下来 $M$ 行,每行包含三个整数 $i$,$t$ 和 $op$,分别表示第 $i$ 个进程在时间 $t$ 进行请求或者释放操作(0 表示释放,1 表示请求)。
输出共 $M$ 行,每行表示对应操作的返回值,如果该操作能立即执行,则输出 1 表示执行成功,否则输出 0。
3 7
0 0 1
1 1 1
2 2 1
1 3 0
0 4 0
2 5 0
1 6 1
1
1
0
1
1
1
0
本题是一道典型的操作系统中进程调度的问题,需要从多个方面考虑进程如何请求和释放公共资源,并且需要按照顺序依次执行请求,直到资源被释放。一般考虑使用队列来实现进程的调度,对于每次请求,如果资源当前被占用,则将该请求加入进程等待队列中,等待资源释放后再依次执行,否则直接执行该请求。对于每次释放操作,则判断等待队列中是否有等待的进程,如果有则依次从队列中弹出加入运行队列中。
根据上述思路,可以设计一个 Process 类来表示每个进程,包括进程的编号、当前请求是否为占用资源,以及进入等待队列的时间戳。同时可以设计一个 std::deque
#include <iostream>
#include <deque>
using namespace std;
class Process {
public:
int pid, ts;
bool acquire;
Process(int pid, int ts, bool acquire) {
this->pid = pid;
this->ts = ts;
this->acquire = acquire;
}
bool operator<(const Process& p) const {
return ts > p.ts; // 时间戳越小,优先级越高
}
};
int main() {
int n, m;
cin >> n >> m;
deque<Process> wait, run;
int cur_ts = 0, cur_pid = -1;
for (int i = 0; i < m; i++) {
int pid, ts, op;
cin >> pid >> ts >> op;
while (!wait.empty() && wait.front().ts == cur_ts) { // 检查等待队列中是否有进程可以运行
if (cur_pid == -1) cur_pid = wait.front().pid; // 如果资源空闲,立即运行等待队列中的第一个进程
run.push_back(wait.front());
wait.pop_front();
}
if (op == 1) { // 请求资源
if (cur_pid == -1) { // 如果资源空闲,则立即占用资源
cur_pid = pid;
run.push_back(Process(pid, ts, true));
cout << 1 << endl;
} else { // 否则将请求加入等待队列中
wait.push_back(Process(pid, ts, true));
cout << 0 << endl;
}
} else { // 释放资源
if (pid == cur_pid) { // 如果是当前进程占用的资源,直接释放
cur_pid = -1;
run.pop_front();
cout << 1 << endl;
} else { // 否则在等待队列中查找对应进程,并将其从队列中删除
bool found = false;
for (int i = 0; i < wait.size(); i++) {
if (wait[i].pid == pid && wait[i].acquire) {
found = true;
wait.erase(wait.begin() + i);
break;
}
}
if (found) cout << 1 << endl;
else cout << 0 << endl; // 如未找到,则说明该请求无效
}
}
}
return 0;
}