QOJ.ac

QOJ

Limite de temps : 2 s Limite de mémoire : 1024 MB Points totaux : 100

#4706. 死锁检测

Statistiques

你正在分析一个包含多个进程和多种资源(如内存页、DMA 通道和 I/O 端口)的系统。每种资源都有一定数量的实例。进程必须获取资源实例才能执行。进程所需的某种资源实例数量取决于该进程本身。进程在获取所有所需资源后,最终会完成执行并终止。随后,这些资源实例会被释放,以便其他进程使用。在终止之前,没有任何进程会释放实例。进程会不断尝试逐个获取所需的资源实例,而不考虑其他进程的行为。由于进程是独立运行的,它们有时可能会因为死锁而无法完成执行。

当不再有所需的资源实例可用时,进程必须等待,直到其他进程在终止时释放资源。死锁是指两个或多个进程相互等待对方终止,且遗憾的是,这种情况会永远持续下去。这种情况发生于以下场景:进程 A 获取了资源 X 的唯一实例,而进程 B 获取了资源 Y 的唯一实例;此后,A 尝试获取 Y 的一个实例,而 B 尝试获取 X 的一个实例。由于除了 B 获取的 Y 实例外没有其他 Y 实例,A 在 B 完成执行前永远无法获取 Y,而 B 在 A 完成执行前也永远无法获取 X。可能存在涉及三个或更多进程的更复杂的死锁情况。

你的任务是接收系统的资源分配时间日志(从系统启动到某个时间点),以确定系统何时进入了“死锁不可避免”的状态。死锁通常可以通过适当的分配顺序来避免,但“死锁不可避免”的状态是指:已经进行了一些资源分配,且从那时起无论采取何种后续分配顺序,都无法避免死锁。

让我们考虑下面样例输入 1 对应的例子。系统有两种资源 $R_1$ 和 $R_2$,以及两个进程 $P_1$ 和 $P_2$。系统有 3 个 $R_1$ 实例和 4 个 $R_2$ 实例。进程 $P_1$ 需要 3 个 $R_1$ 和 2 个 $R_2$ 才能完成执行,而进程 $P_2$ 需要 1 个 $R_1$ 和 3 个 $R_2$。资源分配时间日志如下所示。

时间 事件 $P_1$ 需求 $R_1$ $P_1$ 需求 $R_2$ $P_2$ 需求 $R_1$ $P_2$ 需求 $R_2$ 可用 $R_1$ 可用 $R_2$ 死锁
0 start. 3 2 1 3 3 4
1 $P_1$ acquired $R_1$. 2 2 1 3 2 4
2 $P_2$ acquired $R_2$. 2 2 1 2 2 3
3 $P_1$ acquired $R_2$. 2 1 1 2 2 2
4 $P_2$ acquired $R_1$. 2 1 0 2 1 2 可通过先完成 $P_2$ 避免
5 $P_1$ acquired $R_2$. 2 0 0 2 1 1 不可避免
6 $P_2$ acquired $R_2$. 2 0 0 1 1 0
7 $P_1$ acquired $R_1$. 1 0 0 1 0 0 发生

在时间 4,$P_2$ 获取了 $R_1$,可用 $R_1$ 的数量变得小于 $P_1$ 对 $R_1$ 的需求。因此,$P_1$ 必须等待 $P_2$ 终止并释放该实例。然而,在时间 5,$P_1$ 获取了 $P_2$ 完成执行所需的 $R_2$,因此 $P_2$ 也必须等待 $P_1$;此时死锁变得不可避免。

注意,在时间 4 时,通过先完成 $P_2$ 仍然可以避免死锁(样例输入 2)。

输入格式

输入包含单个测试用例,格式如下:

$p \ r \ t$ $l_1 \dots l_r$ $n_{1,1} \dots n_{1,r}$ $\vdots$ $n_{p,1} \dots n_{p,r}$ $P_1 \ R_1$ $\vdots$ $P_t \ R_t$

$p$ 是进程数量,为 2 到 300 之间的整数。进程编号为 1 到 $p$。$r$ 是资源种类数量,为 1 到 300 之间的整数。资源种类编号为 1 到 $r$。$t$ 是时间日志的长度,为 1 到 200,000 之间的整数。$l_j$ ($1 \le j \le r$) 是资源种类 $j$ 最初可用的实例数量,为 1 到 100 之间的整数。$n_{i,j}$ ($1 \le i \le p, 1 \le j \le r$) 是进程 $i$ 完成执行所需的资源种类 $j$ 的实例数量,为 0 到 $l_j$ 之间的整数。对于每个 $i$,至少有一个 $n_{i,j}$ 不为零。每一对 $P_k$ 和 $R_k$ ($1 \le k \le t$) 表示时间 $k$ 的资源分配日志,意味着进程 $P_k$ 获取了一个资源 $R_k$ 的实例。

你可以假设时间日志是一致的:没有进程会获取不必要的资源实例;没有进程会在终止后获取实例;且进程不会在某种资源实例不可用时获取该资源。

输出格式

输出系统进入“死锁不可避免”状态的时间。如果系统在时间 $t$ 时仍然可以避免死锁,则输出 -1。

样例

样例输入 1

2 2 7
3 4
3 2
1 3
1 1
2 2
1 2
2 1
1 2
2 2
1 1

样例输出 1

5

样例输入 2

2 2 5
3 4
3 2
1 3
1 1
2 2
1 2
2 1
2 2

样例输出 2

-1

Discussions

About Discussions

The discussion section is only for posting: General Discussions (problem-solving strategies, alternative approaches), and Off-topic conversations.

This is NOT for reporting issues! If you want to report bugs or errors, please use the Issues section below.

Open Discussions 0
No discussions in this category.

Issues

About Issues

If you find any issues with the problem (statement, scoring, time/memory limits, test cases, etc.), you may submit an issue here. A problem moderator will review your issue.

Guidelines:

  1. This is not a place to publish discussions, editorials, or requests to debug your code. Issues are only visible to you and problem moderators.
  2. Do not submit duplicated issues.
  3. Issues must be filed in English or Chinese only.
Active Issues 0
No issues in this category.
Closed/Resolved Issues 0
No issues in this category.