Задание №22 — Многопоточность
В файле содержится информация о совокупности N вычислительных процессов, которые могут выполняться параллельно или последовательно. Будем говорить, что процесс B зависит от процесса A, если для выполнения процесса B необходимы результаты выполнения процесса A. В этом случае процессы A и B могут выполняться только последовательно.
Информация о процессах представлена в файле в виде таблицы. В первом столбце таблицы указан идентификатор процесса (ID), во втором столбце таблицы – время его выполнения в миллисекундах, в третьем столбце перечислены с разделителем «;» ID процессов, от которых зависит данный процесс. Если процесс независимый, то в таблице указано значение 0.
Типовой пример организации данных в файле:
| ID процесса B | Время выполнения процесса B (мс) |
ID процесса(-ов) A |
| 1 | 4 | 0 |
| 2 | 3 | 0 |
| 3 | 1 | 1; 2 |
| 4 | 7 | 3 |
Определите максимальную продолжительность отрезка времени (в мс), в течение которого возможно одновременное выполнение четырёх процессов, при условии, что все независимые друг от друга процессы могут выполняться параллельно.
Типовой пример имеет иллюстративный характер. Для выполнения задания используйте данные из прилагаемого файла.
Правильный ответ
7
Пояснение
Решение:
Сначала для каждого процесса вычисляем время старта и время окончания. Независимый процесс стартует в момент 0, а зависимый — сразу, как только завершится последний из тех процессов, от которых он зависит: время старта равно максимуму времён окончания всех его предшественников, а время окончания — старт плюс собственная длительность. Считать удобно рекурсивно, потому что зависимости в файле образуют цепочки.
Для данных из файла получается такое расписание (12 процессов):
| ID | Длительность | Зависит от | Начало | Конец |
|---|---|---|---|---|
| 1 | 4 | — | 0 | 4 |
| 2 | 3 | — | 0 | 3 |
| 3 | 5 | 1; 2 | 4 | 9 |
| 4 | 7 | 3 | 9 | 16 |
| 5 | 6 | 3 | 9 | 15 |
| 6 | 2 | 5 | 15 | 17 |
| 7 | 5 | 4; 6 | 17 | 22 |
| 8 | 2 | 7 | 22 | 24 |
| 9 | 7 | — | 0 | 7 |
| 10 | 8 | — | 0 | 8 |
| 11 | 6 | 9 | 7 | 13 |
| 12 | 6 | 10 | 8 | 14 |
Теперь идём по шкале времени по одной миллисекунде и считаем, сколько процессов активно в каждый момент. Четыре процесса одновременно работают на двух участках: с 0 до 3 мс это процессы 1, 2, 9 и 10, а с 9 до 13 мс — процессы 4, 5, 11 и 12. Больше четырёх процессов не работает никогда.
Складываем длины этих участков: мс.
rows = [(1, 4, []), (2, 3, []), (3, 5, [1, 2]), (4, 7, [3]),
(5, 6, [3]), (6, 2, [5]), (7, 5, [4, 6]), (8, 2, [7]),
(9, 7, []), (10, 8, []), (11, 6, [9]), (12, 6, [10])]
dur = {i: t for i, t, d in rows}
dep = {i: d for i, t, d in rows}
start, finish = {}, {}
def calc(i):
if i not in finish:
start[i] = max([calc(j) for j in dep[i]], default=0)
finish[i] = start[i] + dur[i]
return finish[i]
for i in dur:
calc(i)
total = 0
for t in range(max(finish.values())): # такты по 1 мс
if sum(start[i] <= t < finish[i] for i in dur) == 4:
total += 1
print(total) # 7
Ответ: 7