воскресенье, 28 июня 2009 г.

Одновременность относительна даже в компьютерах

Это перевод Even in computing, simultaneity is relative. Автор: Реймонд Чен.

Эйнштейн обнаружил, что одновременность относительна. Это также применимо и к компьютерам.

Люди часто спрашивают: "Нормально ли делать X в одном потоке и Y в другом одновременно?". Вот несколько примеров:
X = "закрыть дескриптор" и Y = "использовать дескриптор".
X = "вызвать UnregisterWaitForSingleObject для дескриптора", Y = "вызвать UnregisterWaitForSingleObject на него же".

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

Давайте проведём мысленный эксперимент с одновременностью.

Поскольку одновременность относительна, то любой код, который выполняет X и Y одновременно, может быть наблюдаем как выполняющий X перед Y или Y перед X, в зависимости от выбора точки отсчёта. Так работает Вселенная.

Поэтому, если бы было допустимо делать их "одновременно", тогда было бы допустимым выполнять их в любом другом порядке, один за другим, поскольку они возникают именно один за другим, если вы пройдёте мимо компьютера в нужном направлении.

Нормально ли использовать дескриптор после закрытия? Нормально ли отменять регистрацию ожидания на событии дважды?

Ответ на оба вопроса - "Нет", и поэтому не допустимо выполнять их и одновременно.

Если вам не нравится использование физики для решения этой проблемы, вы также можете подойти к этому с чисто технической точки зрения.

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

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

Надеюсь, это второе объяснение удовлетворит людей, кто не верит в силу физики. Лично я предпочитаю первое объяснение.

Прим. пер.: кроме того, на одноядерной/однопроцессной машине процессор в один и тот же момент времени может выполнять только один поток. О какой одновременности вообще может идти речь в таких условиях?

9 комментариев:

  1. Разве в многоядерной конфингурации, два ядра не будут одновременно решать разные задачи?

    ОтветитьУдалить
  2. Смотря что понимать под "одновременно".
    На многоядерной машине в каждый момент времени может выполняться может более одного потока одновременно. Это так.
    Однако говорить об одновременности двух событий у этих двух потоков всё равно нельзя. Именно это демонстрируется этим постом.

    ОтветитьУдалить
  3. Случаем нет желания перевести вот это - http://sjrd.developpez.com/delphi/tutoriel/generics/
    ?:)

    ОтветитьУдалить
  4. Больно жирно будет - это больше похоже на книгу или часть книги ;)
    Я же не профессиональный переводчик, чтобы книги переводить.
    Я просто программист, который полчаса в день отводит на перевод интересных постов, аналогов которых на русском не найти.

    ОтветитьУдалить
  5. Ну так, там же вроде не большие главы :)
    Да и вроде аналогов на русском пока нет :)

    Ну вобщем это просто в качестве предложения, возможно когда нибуть :)

    ОтветитьУдалить
  6. > Случаем нет желания перевести вот это ... ?

    У меня есть. Спасибо за ссылку. =)

    ОтветитьУдалить
  7. > У меня есть
    Хе-хе, ловим на слове ;)

    ОтветитьУдалить
  8. Не прошло и полгода, а перевод уже закончен.
    S'il_vous_plaît, генерики в Delphi 2009

    ОтветитьУдалить

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку.

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.

Примечание. Отправлять комментарии могут только участники этого блога.