Виртуализация ЦПУ

Вопрос или проблема

Понимание виртуализации ЦП в операционных системах: концепции и реализация

Неожиданное поведение при запуске нескольких экземпляров программы для выделения памяти

Я изучаю операционные системы и следую учебнику OSTEP (Операционные системы: три простых части). Я пытаюсь понять виртуализацию памяти, запускаю несколько экземпляров программы одновременно. Вот код, с которым я работаю:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include "common.h"

int main(int argc, char *argv[]) {
    int *p = malloc(sizeof(int)); // a1
    assert(p != NULL);
    printf("(%d) адрес, на который указывает p: %p\n", getpid(), p); // a2
    *p = 0; // a3
    while (1) {
        Spin(1);
        *p = *p + 1;
        printf("(%d) p: %d\n", getpid(), *p); // a4
    }
    return 0;
}

Согласно учебнику, при выполнении с командой ./mem &; ./mem & эта программа должна продемонстрировать виртуализацию памяти, запуская два экземпляра одновременно. В тексте говорится:

Из примера видно, что каждая работающая программа выделила память по тому же адресу (0x200000), и тем не менее каждая, кажется, обновляет значение по 0x200000 независимо! Это как если бы каждая работающая программа имела свою собственную частную память, вместо того чтобы делить ту же физическую память с другими работающими программами. Действительно, именно это здесь и происходит, поскольку ОС виртуализирует память.

Однако, когда я запускаю эту программу локально, я получаю следующий вывод:

вывод локального запуска

Оба экземпляра не работают одновременно, как ожидалось. Что может вызывать такое поведение? Мне чего-то не хватает в настройках или понимании того, как это должно работать?

Дополнительная информация:

  • Операционная система: Microsoft Windows 11 Home Single Language
  • Версия операционной системы: 10.0.22631 N/A Build 22631
  • Компилятор: gcc (MinGW.org GCC-6.3.0-1) 6.3.0

Введите это в bash, и это сработает.

& означает запуск в фоне в bash, но это означает что-то другое в PowerShell; я удивлён, что вы не получили сообщение об ошибке.

Символ & в конце команды является директивой bash (т.е. командной строки Linux / Unix) для запуска программы в фоновом режиме. У него нет этой функциональности в Windows.

Самое простое, что можно сделать, это открыть два отдельных командных окна и запустить программу в каждом из них примерно в одно и то же время.

Ответ или решение

Виртуализация ЦП в Операционных Системах: Понимание и Реализация

Введение в виртуализацию ЦП

В виртуализации ЦП подразумевается создание абстракции, позволяющей нескольким операционным системам или приложениям работать в пределах одной физической машины, так как будто каждый из них имеет свой собственный изолированный набор ресурсов. Это достигается благодаря механизму управления памятью, который предоставляют современные операционные системы.

Проблема, с которой вы столкнулись

В рамках вашего эксперимента с кодом, приведенным в вашем вопросе, вы заметили неожиданные проблемы при попытке запустить две инстанции программы для выделения памяти. Ожидалось, что каждая программа будет иметь возможность независимо обновлять значение по одному и тому же адресу в памяти, что демонстрирует концепцию виртуализации памяти. Однако вместо этого вы столкнулись с тем, что оба процесса не работают одновременно.

Анализ кода

Ваш код включает в себя выделение памяти с помощью malloc и бесконечный цикл, в котором каждый процесс увеличивает значение переменной p. Теоретически, так как каждая инстанция программы изолирована в своей виртуальной памяти, каждая должна работать независимо от другой.

Код работает следующим образом:

  1. Выделение памяти.
  2. Вывод адреса выделенной памяти.
  3. Бесконечный цикл, где происходит работа с выделенной памятью и вывод результата.

Почему наблюдается такое поведение?

Вы упомянули, что используете операционную систему Windows и запускаете команду ./mem &; ./mem &. На самом деле, символ & в командной строке Bash (Linux/Unix) используется для запуска процесса в фоновом режиме. В PowerShell (Windows) он не выполняет ту же функцию, что может привести к тому, что обе инстанции программы не запускаются одновременно.

Решение проблемы

Для того чтобы корректно протестировать программу и увидеть ожидаемый результат, существует несколько подходов:

  1. Использование нескольких окнах командной строки. Откройте два разных командных окна (Command Prompt) и запустите ./mem в каждом из них. Это позволит обоим процессам выполняться одновременно, и вы сможете увидеть, как они обрабатывают память независимо друг от друга.

  2. Использование альтернативной среды. Если возможно, рассмотрите использование WSL (Windows Subsystem for Linux), который позволяет запускать много команд Linux в Windows. В этом случае команда с символом & будет работать, как ожидалось.

  3. Запуск в PowerShell. Вы можете использовать фоновый запуск в PowerShell с помощью Start-Process, что позволит аналогично запускать процессы параллельно.

Заключение

Ваш опыт с виртуализацией ЦП и управлением памятью в операционных системах действительно демонстрирует принципиально важные аспекты работы с процессами и памятью. Виртуализация позволяет каждому процессу функционировать так, как будто он единственный, находящийся на своей машине, даже если физические ресурсы совместно используются другими процессами. Для верной проверки теории выполнения вашего кода важно учитывать особенности командной строки вашей операционной системы.

Оцените материал
Добавить комментарий

Капча загружается...