LINUX.ORG.RU

Года бегут, а все-равно ваш C++ - ...

 ,


1

9

В соседнем треде промелькнула очень интересная мысль.

Отличие синьора-помидора на C++ от мидла в том, что последний уже знает что C++ говно, но еще не знает, почему.

Внимание, вопрос уровня синьора-помидора. Дан код. Объясните, почему другой синьор-помидор обосрался, написав его? Где может обосраться пользователь?

Задачу не будем усложнять, допустим, у нас single producer - single consumer предполагается.

#ifndef __BLOCKING_QUEUE_HPP__
#define __BLOCKING_QUEUE_HPP__

#include <cstdlib>
#include <mutex>
#include <condition_variable>

template<typename T>
class BlockingQueue
{
private:

    struct QueueNode
    {
        T val;
        QueueNode * next;
    };

    QueueNode *_first, *_last;
    std::mutex _cs;
    std::condition_variable _cv;
    bool _abort;
    int _count;

public:

    BlockingQueue()
    {
        _first = _last = nullptr;
        _abort = false;
        _count = 0;
    }

    ~BlockingQueue()
    {
        Flush();
    }
    
    BlockingQueue(const BlockingQueue& rhs) = delete;

    void operator=(const BlockingQueue& rhs) = delete;

    bool Put(const T& val)
    {
        std::unique_lock<std::mutex> lock(_cs);

        if(!_abort)
        {
            QueueNode * node = (QueueNode*)malloc(sizeof(QueueNode));
            if (node)
            {
                new (&node->val) T(val);
                node->next = nullptr;
                if (_last)
                    _last->next = node;
                else
                    _first = node;
                _last = node;
                ++_count;
                _cv.notify_one();
                return true;
            }
        }
        return false;
    }

    bool Get(T& val)
    {
        std::unique_lock<std::mutex> lock(_cs);

        for (;;)
        {
            if (_abort) return false;

            QueueNode * node = _first;
            if (node)
            {
                _first = node->next;
                if (!_first) _last = nullptr;
                --_count;
                val = node->val;
                node->val.~T();
                free(node);
                return true;
            }
            else
            {
                _cv.wait(lock);
            }
        }
    }

    int Count()
    {
        return _count;
    }

    void Flush()
    {
        QueueNode *node, *tmp;

        std::unique_lock<std::mutex> lock(_cs);

        for (node = _first; node; node = tmp)
        {
            tmp = node->next;
            node->val.~T();
            free(node);
        }

        _first = nullptr;
        _last = nullptr;
        _count = 0;
    }

    void Abort()
    {
        std::unique_lock<std::mutex> lock(_cs);
        _abort = true;
        _cv.notify_one();
    }

    void Start()
    {
        std::unique_lock<std::mutex> lock(_cs);
        _abort = false;
        _cv.notify_one();
    }
};

#endif // __BLOCKING_QUEUE_HPP__

Вопрос номер два - назовите хотя бы один язык программирования с подобными проблемами.

★★★

Лавсанчик, ну козе понятно, шо плюсы - говно, но какого пушкина ты в них полез?

anonymous
()
Ответ на: комментарий от MyTrooName

Он на unix shell, причем кем-то не знающим что такое cat.

anonymous
()
Ответ на: комментарий от anonymous

а вот это науке непонятно. свирепые рукожопы страдают от c++ но нагло продолжают на нем писать.

хотя могли бы писать божественные аппликухи на цацкеле или жабе

i36_zubov
()
Ответ на: комментарий от i36_zubov

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

anonymous
()
Ответ на: комментарий от i36_zubov

цацкеле или жабе

смешались в кучу кони люди

anonymous
()
Ответ на: комментарий от i36_zubov

Ты утверждаешь, что писать на си++ говнокод — это черта характерная лишь для рукожопов? Это ложь! На с++ просто невозможно писать хорошо!

anonymous
()
Ответ на: комментарий от anonymous

На с++ просто невозможно писать хорошо!

типичная заявка типчного рукожопа типа лавсанчика.

anonymous
()
Ответ на: комментарий от anonymous

Приведи пример хорошего кода на с++ (желательно написанного тобой лично, раз уж ты нерукожоп). Всё вменяемое написано на голом Си!

anonymous
()
Ответ на: комментарий от anonymous

Эдди, именно тебя не хватало в этом зоопарке!

anonymous
()
Ответ на: комментарий от anonymous

А я си-плюх-плюхой никогда не пользовался.

Вот ведь. Прям классика «Пастернака не читал, но осуждаю...»

eao197 ★★★★★
()
Ответ на: комментарий от i36_zubov

Не, я на крестах без проблем пишу. Но у меня они не ассоциируются навязчиво с туалетной тематикой, к чему бы это? %)

anonymous
()

Более того. Это не может быть сеньер. Т.к. весь дизайн - говно. Глобальный lock на put/get? Студентов отучают так делать на третьем курсе.

invy ★★★★★
()
Ответ на: комментарий от anonymous

ну не пиши на с++. зачем ты вообще говнокод пишешь? прекрати писать говнокод. не пиши его. или спину почеши, попрыгай, что нибудь ещё когда очень сильно накатывает желание поговнокодить.

зачем ты, жопа с ручками, вообще на с++ пишешь?

ckotinko ☆☆☆
()
Ответ на: комментарий от lovesan

Если не нравится технология, то зачем себя истязать? Перейдите на другую технологию и всё. Вам же только лучше будет

zamazan4ik ★★
()

Присоединяюсь к тем в треде, кто не верит, что это синьор-помидор писал. Не может такого быть

zamazan4ik ★★
()
Ответ на: комментарий от invy
Глобальный lock на put/get? Студентов отучают так делать на третьем курсе.

Так, стопэ, я не понял... Ты хочешь сказать, что где-то существует университет, в котором учат писать код? Это вообще возможно?

anonymous
()
Ответ на: комментарий от zamazan4ik

Знатные аргументы у плюх-плюхеров. Тому кто на плюхе пишет и давится они говорят не пиши на плюхе. Тому кто на плюхе не пишет они тычут Пастернаком. Адептам плюх-плюха можно посоветовать зарегистрироваться в качестве религиозной группы. Уверен плюх-плюхианство окажется весьма заразительным. И быть может однажды какому-нибудь плюх-плюхианскому патриарху удастся пропихнуть закон об оскорблении чувств плюх-плюхиан.

anonymous
()
Ответ на: комментарий от anonymous

Тому кто на плюхе пишет и давится они говорят не пиши на плюхе. Тому кто на плюхе не пишет они тычут Пастернаком.

Дык логично же: давишься — не ешь, не пробовал — не берись судить о вкусе. Не?

Или смысл был лишь в потуге на испражнение остроумия?

eao197 ★★★★★
()

И вновь передаем микрофон товарищу лавсану

С годами, мое мнение, что идейные C++ программисты — просто ебаные невменяемые задроты, аутисты и неадекваты, только подтверждается.

Их не волнует ни сдача продуктов, ни сложность дебага, ни даже красота и простота кода. Ни концепции, ни идеи, ни логика, ни продакшн, ни даже бабки. Нихуя.

Их волнует только то, как бы выдрочиться в кругу таких же задротов: Смотрите! Я знаю шаред_птр! А я! А я! Интрузив_птр! А я знаю как правильно писать деструкторы! А я вчера квиксорт написал и он не сегфолтится! А я буст воткнул в проект! А я! Мама, смотря, я на темплейтах написал числа фибоначчи!

Пиздец блядь, гвозди бы делать из этих людей.

http://juick.com/lovesan/2870509

anonymous
()

Как это все связано конкретно с с++?

pathfinder ★★★★
()
Ответ на: комментарий от invy

я код не читал, т.к. ожидал чего то подобного. и собственно не удивлен.

это тупое чучело еще и понты колотит, как тут пишут.

вообще, c++ это какой то детектор рукожопых

i36_zubov
()
Ответ на: комментарий от anonymous

мда...

и добавить-то нечего. собственно говнокод в сабже и этот понтотекст образуют законченное произведение исскуства. памятник рукожопу

i36_zubov
()

Автор в конструкторе не использует мьютекс - он уже проиграл. Рекомендации - читать спеку модели памяти C++ до просветления.

dzidzitop ★★
()
Последнее исправление: dzidzitop (всего исправлений: 2)
Ответ на: комментарий от anonymous

Да. У нас на «распределенных системах» был разбор ботлнеков возникающих от таких глобальных локов на весь контейнер. И задание - обедающие философы с rpc, синхронизацией, и по сети с инстансами работающими на гетерогенных системах.

invy ★★★★★
()
Последнее исправление: invy (всего исправлений: 1)
Ответ на: комментарий от invy

Глобальный lock на put/get? Студентов отучают так делать на третьем курсе.

Студентов-то может быть и отучают. А в продакшене... Здесь-то хоть все локи на месте. Вроде.

Кстати, глобальный лок это не так и плохо. Это, даже можно сказать, и хорошо! Гранулярность локов в говнокоде — зверюга покруче Ктулху.

А вот отсутствие ограничения на размер... Стоит только «принимающей стороне» чуть-чуть заплипнуть. Но опять, практика показывает, что и это не то чтобы очень плохо.

Macil ★★★★★
()
Ответ на: комментарий от Macil

А вот отсутствие ограничения на размер... Стоит только «принимающей стороне» чуть-чуть заплипнуть. Но опять, практика показывает, что и это не то чтобы очень плохо.

Практика, да и здравый смысл, показывают, что существует мн-во способов ограничить очередь не делая ограничений в самой очереди. Например, получатель может раздавать фиксированный объём токенов генераторам потока за одно добиваясь честного деления очереди, а может и ограничиваться какими-либо естествнными условиями.

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

anonymous
()
Ответ на: комментарий от anonymous

прекрасный кросплатформенный ассемблер

С каких пор язык, в котором не определены даже размеры базовых типов, становится 1) кроссплатформенным 2) ассемблером? Хрен какой-то ляпнул один раз что раз указатели, то значит сложно и значит «ассемблер», а потом уже народные массы разносят этот бред.

dzidzitop ★★
()
Последнее исправление: dzidzitop (всего исправлений: 1)

Лавсанчег, вечно ты вступаешь куда-то: то в партию, то в венду, то в лисп, то в плюсы.

nezamudich ★★
()
Ответ на: комментарий от ckotinko

зачем ты, жопа с ручками...

Не трожь моего брата! (если аватарки отключены, включи и посмотри на мою).

deep-purple ★★★★★
()
Ответ на: комментарий от anonymous

Хотел сказать, что это был другой лавсан, другое время было. А потом посмотрел на дату цитируемого текста)

nezamudich ★★
()

Это необучаемость или магическое мышление, сидя на жёппе ровно ждать что время сконвертируется во что-то там? ))

anonymous
()
Ответ на: комментарий от kawaii_neko

Типичная история крестомакакенов.

Только это лиспомакакен.

DarkEld3r ★★★★★
()
31 августа 2017 г.
Ответ на: комментарий от kawaii_neko

Дело не во мьютексе. Дело в том, что у компилятора нет никакой причины считать, что вызов _cv.wait() может повлиять на значение _abort, поэтому проверка if(_abort) может быть вынесена за тело цикла.

Ну давай разберём по частям тобою написанное. Что делает wait:

  • Отпускает мьютекс — это release operation. Блочит тред.
  • При разблокировке треда захватывает мьютекс — это acquire operation.

Никакие операции чтения, которые следуют за acquire operation, не могут быть переупорядочены с этой операцией. Чтение _abort в условии if следует за захватом мьютекса поэтому вынесено за тело цикла быть не может, т.к. это означало бы переупорядочивание с acquire operation.

utf8nowhere ★★★
()
Ответ на: комментарий от lovesan

в стандартной библиотеке крестов подобного класса нет до сих пор

Подобного — это как в ОП-посте?

utf8nowhere ★★★
()

блокировки - моветон, man erlang

anonymous
()
Ответ на: комментарий от utf8nowhere

Ну давай разберём по частям тобою написанное

Я рад, что ты выучил модные фигуры речи, однако не мешает подтянуть матчасть, да и вообще научиться читать, прежде чем отвечать: компилятор вправе счесть, что _abort не меняется внутри бесконечного for и вынесет эту проверку перед выполнением цикла. И memory ordering тут ни при чем.

kawaii_neko ★★★★
()
Ответ на: комментарий от kawaii_neko

компилятор вправе счесть, что _abort не меняется внутри бесконечного for

Не вправе.

И memory ordering тут ни при чем.

Ещё раз, для не умеющих читать: _cv.wait() анлочит и опять лочит мьютекс. Проверка if (_abort), таким образом, находится внутри критической секции. Если ты считаешь, что компилятор вправе выносить произвольный код из критической секции — тебе стоит подтянуть матчасть.

utf8nowhere ★★★
()

Тут только за одну попытку навелосипедить на ровном месте аналог стандартного контейнера надо код полностью выкидывать.

anonymous
()
Ответ на: комментарий от utf8nowhere

Если ты считаешь, что компилятор вправе выносить произвольный код из критической секции — тебе стоит подтянуть матчасть

Если ты считаешь, что компилятор хоть что-нибудь знает о «критической секции», тебе пора выйти вон из айти.

kawaii_neko ★★★★
()
Ответ на: комментарий от kawaii_neko

Компилятор знает о том, что лок мьютекса это acquire operation. И это накладывает ограничения на возможные оптимизации, связанные с переупорядочиванием чтения и записи.

Про «критические секции» было написано упрощённо (после того, как до тебя не допёрло описание через memory ordering), но и оно для тебя слишком сложно, как я вижу.

utf8nowhere ★★★
()
Ответ на: комментарий от dzidzitop

Хрен какой-то ляпнул один раз что раз указатели, то значит сложно и значит «ассемблер»

Это ты сам этого хрена придумал? Термин «переносимый ассемблер» появился как иллюстрация того, что на сишке можно делать низкоуровневые вещи, и при этом не прибиваться гвоздями к архитектуре конкретного процессора. Указатели тут только одна из возможностей писать эффективный код, «сложность» вообще не при чём.

А что размеры базовых типов не определены - так это как раз ради переносимости. Есть процессоры, для которых наиболее эффективной будет 16-разрядная арифметика, есть такие, у которых 64-разрядная. Другое дело, что выиграв в одном, язык потерял в другом, т.к. в некоторых ситуациях типы фиксированного размера таки нужны. Яркий пример - разбор двоичных файлов и сетевых протоколов. Между прочим, у меня на полке стоит справочник по Си года издания где-то так 1990го, в котором как раз разбирались вопросы переносимости, и где как раз настоятельно рекомендовалось ради неё, родимой, в файлы писать текстовое представление, а не двоичное.

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

hobbit ★★★★★
()
Ответ на: комментарий от utf8nowhere

Компилятор знает о том, что лок мьютекса это acquire operation

Откуда? В общем случае это тупо вызов библиотечной функции. И не факт, что там есть какие-либо аннотации.

anonymous
()
Ответ на: комментарий от kawaii_neko

Дело в том, что у компилятора нет никакой причины считать, что вызов _cv.wait() может повлиять на значение _abort, поэтому проверка if(_abort) может быть вынесена за тело цикла.

Наоборот, нет никакой причины считать, что вызов не может повлиять на переменные, т.к. «внешняя» функция может натворить все что угодно, например, хранить указатель на _abort и менять его.

anonymous
()
Ответ на: комментарий от anonymous

Откуда?

Внезапно, из стандарта.

В общем случае это тупо вызов библиотечной функции. И не факт, что там есть какие-либо аннотации.

Как соответствовать стандарту, не имея аннотаций, сам догадаешься или подсказать?

utf8nowhere ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.