1. C++ / Говнокод #4937

    +162

    1. 1
    2. 2
    while(!ThreadActivateFlag)
      Sleep(0);

    Запостил: Говногость, 15 Декабря 2010

    Комментарии (46) RSS

    • показать все, что скрытои что хуйня из какой-нибудь лабороторной
      Ответить
      • ты про себя?
        Ответить
      • как ты выбрался из автоклава?
        Ответить
        • Как, как... Видимо профессор Выбегалло недоглядел..
          Ответить
          • Я раньше думал, что Аркадий и Борис фантастику писали. Оказывается, всё было на самом деле.
            Срочно выручайте! Если не успеем, он свернёт горизонт и захавает мир!
            Ответить
            • не, он один ничего не сделает, ему нужно собрать ещё трёх поней для следующего уровня...
              Ответить
        • Ты его не грузи так, это, кажется, не входит в школьную программу по литературе за 8 класс, так что он не поймёт.
          Ответить
    • Это типа такой говносемафор?
      Ответить
    • Тут достаточно Sleep(100) поставить и станет все нормально.
      Ответить
      • со 100 можно и опоздать на поезд
        Ответить
      • Функция Sleep не осуществляет возврата до тех пор, пока не истечет указанное время. В течение него выполнение потока приостанавливается и выделения для него процессорного времени не происходит (хотя очевидно, что для потока все-таки требуется какое-то незначительное время, за которое система должна определить, пора возобновлять выполнение потока или нет). Если параметр функции Sleep задан равным нулю, то поток будет лишен остатка выделенного ему кванта процессорного времени.
        Ч. Петзолд "Программирование для Windows® 95 в двух томах" Том 2 стр. 41

        Так что Sleep(0) там нормально стоит, но светофор однозначно глючить будет.
        Ответить
        • тру, но вообще ждать объекта (∞)
          Ответить
          • Надо "ждать" того, что надо "ждать" в каждом конкретном случае.

            Для "мелкодисперсной" синзхронизации с коротким временеим ожидания - именно spin-lock, как показано выше, и ни в коем случае не "ждать объекта".

            "Ждать объекта" - это только для грубой синхронизации с длительными спячками. "Объектами" синхорнизируют GUI, IO и т.п. тяжеловесные вещи.

            Вычисления же синхронизируются имено во таким spin-lock-ами. Это если вам нужна эффективность, конечно.
            Ответить
            • Нет сдесь Spin блокировки. Смотри ниже:
              http://www.govnokod.ru/4937#comment58422
              Ответить
              • "Ниже" написан какой-то необъяснимый бред. Я, вроде, все понятно объяснил "ниже".
                Ответить
                • Всеже, прошу пояснить свою позицию, относительно http://govnokod.ru/4937#comment58917 в низу.
                  Ответить
    • Поток - эгоист,
      И недоучка - программист.
      Ответить
    • Поток едет в автобусе сидя, около него стоит бабуля. В первой строке он приоткрывает один глаз, посмотреть ушла ли, а во второй делает вид что спит. Правда так на нервный тик похоже больше.
      Ответить
    • Опять поток бреда в комментариях! Какой еще "потока-эгоист"? Какой еще "убей-цпу"? Поленья, читайте основы многопоточной синхронизации!

      Приведенный код - простейшая классическая реализация spin-lock. Фукция `Sleep` с параметром `0` в WinAPI имеет особый смысл и особое назначение. `Spin(0)` означает "передать остаток временного слайса следующему готовому к выполнению потоку". Т.е. это сделано именно для того, чтобы не грузить процессор бессмысленным мотанием по пустому циклу, а вместо этого передать ненужный остаток временного слайса дальше, на полезную работу. Т.е. никакого потока-эгоиста тут нет. Все в точности наоборот: налицо корректно и умышленно примененый прием, делающий поток НЕ эгоистом.

      Spin-lock - исключительно полезный синхронизационный примитив. Придираться в данном случае можно было бы к оформлению: вместо выделенного примитива, реализация spin-lock протя вписана явно в код - это криво. Отдельно стоило бы рассмотреть традиционный вопрос применения spin lock вместо системного sleep-lock, но об этом без контекста говорить не приходится.
      Ответить
      • Опечатка. Должно быть `Sleep(0)` означает "передать остаток временного слайса следующему готовому к выполнению потоку
        Ответить
      • Много текста. Вы сильно серьёзно ко всему относитесь. Найдите себе девушку.
        Ответить
        • Не для "поколения Пепси" пишу.
          Ответить
        • Пришёл, заминусовал, затроллил. Молодец, возьми с полки пирожок и сделай, наконец, уроки! Человек вроде что-то умное пишет, если ты не осиливаешь - то это только твои проблемы, а не его.
          Ответить
        • Опять же, извиняюсь за эту выходку. О, если бы все так старались, как Вы, жизнь была бы лучше.
          Ответить
      • Sleep(0) не равно Spin блокировке. Поэтому профита от этого не будет в данном случае. Лишь вред из-за пожирания проца. Так что это не умышленный приём, а говно.
        Ответить
        • Что за бред? Спин-блоктировка - это не `Sleep(0)`, это всесь цикл с `Sleep(0)` внутри. Классическая простейшая хрестоматийная спин-блокировка, буква в букву. Задача `Sleep(0)`, как ясно сказано выше, - передать "неиспользованный" остаток временного слайса обратно системе для "полезного использования".
          Ответить
          • Извините, возникло взаимонепонимание. Сбило то, что Вы из-за опечатки обозвали Sleep - Spin'ом. Поэтому думал, что вы не про цикл, а конкретно про Sleep.
            Все объяснил ниже в http://www.govnokod.ru/4937#comment58917
            Ответить
    • Кстати, забавно, что у этого кода так мало плюсов. Неужели, все всерьёз пользуются этим говном для ожидания потоков, нежели через ожидание на событиях?
      Ответить
      • Проснулся... "Ожидание потоков" в реальном коде делается именно и только так. Производительность ожидания на системных объектах ("событиях" и т.п.) слишком низка и потому совершенно неприемлема в реальном высокопроизводительном коде. Ожидания "на событиях" делатся, каке я сказа выше, только для медленных и "тяжелых" операций, типа GUI, ввода-вывода и т.п.

        Отдельно стоит заметить, что, например, виндушный CRITICAL_SECTION - это внутеренне ни что иное, как гибрид spin-lock (вот именно такого, как приведено выше) и "ожидания события" (там семафор внутри, на самом деле). Сначала делается ожилание по spin-lock, и только потом, если дождаться не удалось, делается постановка на "ожидание события". Именно из-за грамотного использования spin-lock можно достичь существенно лучшей производительности CRITICAL_SECTION по сравнению с mutex.
        Ответить
        • >spin-lock
          >CRITICAL_SECTION
          >mutex
          ребятки, не хотел вас расстраивать, но 70е кончились.
          Ответить
          • А как верно на данный момент?
            Ответить
            • на данный (и не только) актуален подход эрланга. еще, допустим, clojure (STM).
              для асинхронности без заморочек само собой CPS и корутины - stackless python, twisted, go..
              Ответить
              • А что Вы думаете о примитивах синхронизации из нетфреймворк?
                Ответить
              • Поток сознания. Все эти рассуждения относятся к области "а вот как было бы хорошо если бы..." с мечтателными детскими глазенками, смотрящими в голубое июньское небо.

                А в реальной жизни у нас есть то, что в советском вузе называлось "семантическим разрывом между архитектурой ЭВМ и абстрактными языками программирования". И все эти эрланги-шмерланги в конечном итоге посторены вот на таких же спин-локах (больше попросту не на чем строить). А STM - это хорошо... Вот бы если бы оно еще в реальности приемлемо работало... (все из-за того же семантического разрыва).

                Пока в машинных архитектурах царят 70-е, эти 70-е в программировании не закончатся. А всякие эрланги-шмерланги по этой причине годны только для написания разных "хелловорлдов" и т.п...
                Ответить
                • да??
                  хотя к императиво..м нужно как к детишкам, измазавшимся говн... нет, просто промолчу.
                  Ответить
        • Пример реализации спинлока на ассемблере x86:

          mov eax, spinlock_address
          mov ebx, SPINLOCK_BUSY
          wait_cycle:
          lock xchg [eax], ebx
          cmp ebx, SPINLOCK_FREE
          jnz wait_cycle
           
          ;<спинлок захвачен данным процессором, работа с разделяемым ресурсом>
           
          mov eax, spinlock_address
          mov ebx, SPINLOCK_FREE
          lock xchg [eax], ebx


          Нет никакого sleep. Смысл спинлока в том, что-бы не отдавать управление другому потоку на многоядерных системах, тк это медленно. А Sleep как раз отдаёт управление другому потоку. В данном случае цикл быть спинлоком не может, раз отдаёт управление другому потоку.
          Ответить
        • Этот цикл в этом говнокоде просто не может быть спинлоком по определению
          http://ru.wikipedia.org/wiki/Spinlock
          , тк отдаёт управление другому потоку в каждой итерации.

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

          Спинлок обычно применяется именно совместно с событиями. Притом спинлок применяется только на многопроцессорных машинах. Сначало пытаемся ждать по спинлоку, но если не дождались за короткий период времени, то уже возвращаем управление другим потокам, что-бы зря не занимать процессор.
          Ответить
    • Вы достойны лобызать мои ноги!
      Ответить
    • А в исходниках только один поток?
      Если да, то гавнокод :)
      Если есть другие потоки, которые манипулируют с этой переменной, то такое возможно при работе с аппаратурой. К примеру: прослушка порта и получение данных с датчиков, счетчиков и т.д. в очень короткие интервалы времени и на загрузку процессора вообще насрать, если хоть один бит мимо пройдет.
      Ответить

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