Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: 1 2 [Все]   Вниз
  Печать  
Автор Тема: Атомарность операций над стандартными типами C++  (Прочитано 20286 раз)
0 Пользователей и 1 Гость смотрят эту тему.
RuNTiME
Помогающий

ru
Offline Offline
Пол: Мужской

« : 10-08-2011 17:45 » 

Есть переменная, тип int. Два потока пишут в эту переменную, а третий считывает значение этой переменной. Запись синхронизирована мьютексом, чтение не синхронизировано. Собственно вопрос в том, безопасно ли считывать значение этой переменной? Что будет, если потоки начнут одновременно читать и писать в эту переменную?
Записан

Любимая игрушка - debugger ...
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #1 : 10-08-2011 17:48 » 

Тут надо спросить, а сколько процессоров есть? Если один, то ничего не будет. Да и со множеством процессоров я так думаю ничего не будет. Операция чтения из памяти превращается в ассемблерную команду MOV AX, [SOME_ADRESS] Для потока гарантировано, что регистры не будут изменять свои значения. Но если у тебя например читаюший поток несколько раз использует одну и туже переменную для вычисления какой либо формулы, то тут могут быть и приключения. Так как во время вычисления, значение будет считываться несколько раз.
« Последнее редактирование: 10-08-2011 17:57 от Finch » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
RuNTiME
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 10-08-2011 17:52 » 

Хотелось бы рассмотреть общий случай, пусть будет произвольное количество процессоров/ядер  Улыбаюсь
Записан

Любимая игрушка - debugger ...
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #3 : 10-08-2011 17:55 » 

Дописал для обшего случая Улыбаюсь
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
RuNTiME
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 10-08-2011 18:01 » 

Хмм, в общем я так понимаю, если размер переменной не превышает размер регистра процессора, то операция чтения будет атомарной. Но если к примеру попытаться провернуть такой финт с 64 битной переменной на 32 разрядном процессоре, словим глюк.
Записан

Любимая игрушка - debugger ...
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #5 : 10-08-2011 18:06 » 

Не обязательно. На x86 процессорах младшие биты идут всегда первыми. А старшие биты относительно редко будут меняться. Хотя это все дело случая. И отлавливать внезапные ошибки будет сложновато.

Кстати, тип int по стандарту всегда равен разрядности системы. Хотя я встречал для 64 разрядных систем, что тип int был 32 разрядный.
« Последнее редактирование: 10-08-2011 18:09 от Finch » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #6 : 11-08-2011 04:14 » 

тут не важно 32 или 64, процессор в любом случае не оперирует столь маленькими кусками при чтении памяти, он оперирует кэш линиями, оба этих типа не могут быть разделены на 2 кэш линии, если ты конечно не делаешь грязный хак ввиде копирования char * в int через reintepret_cast
так же нужно помнить, про volitile - без него даже защищённая мьютексом переменная может давать спецэффекты
а кроме всего прочего вопрос атомарно ли чтение или запись не сильно полезен в большенстве случаев, не так уж часто нужно просто изменить переменную или прочитать, обычно перед или после с переменной, что-то делают и нужно смотреть, что именно возможно тут нужно сделать копию переменной или же защищать мьютексом все вычисления зависящие от переменной, защищать непосредственно запись часто безсмысленно (когда мы говорим о таком объекте как int)
Записан

Странно всё это....
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #7 : 11-08-2011 06:28 » 

Кроме всего прочего ещё есть функции, специфичные для каждой платформы, для работы с atomic-переменными, например семейство Interlocked*() в win или atomic_*() в unix-подобных.
« Последнее редактирование: 11-08-2011 06:33 от darkelf » Записан
RuNTiME
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #8 : 11-08-2011 06:50 » 

Антон (LogRus), Если переходить на конкретный случай, то эта переменная отражает состояние в классте потока. Что - то навроде "Новый", "Запущен", "Приостановлен", "Остановлен". И защищать на запись обязательно т.к. изменять её могут множество потоков, которым требуется управлять данным классом потока. И да, безусловно защищены все вычисления и манипуляции приводящие к изменению этой переменной. Под вопросом только считывание этого состояния без блокирования переменной. Насчет volatile, которая отключает оптимизацию переменной, думаю что побочных эффектов не будет, если защищен весь код, который изменяет эту переменную.

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

PS: Посмотрел реализацию потоков в библиотеке wxWidgets там переменную состояния потока на чтение не защищают...
Записан

Любимая игрушка - debugger ...
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #9 : 11-08-2011 07:33 » 

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

ru
Offline Offline
Пол: Мужской

« Ответ #10 : 11-08-2011 07:42 » 

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

Вот выдержка из описания к переменной atomic_t:
These functions manipulate variables of type atomic_t is SMP and interrupt safe ways. These variables can be used to hold spin locks or SMP-safe reference counters. These functions guarantee that the operation that they represent is performed correctly. If necessary, hardware bus locking is performed to protect the operation. Usually, the CPU has some sort of atomic instructions that allow these operations to be performed quickly and safely.
« Последнее редактирование: 11-08-2011 07:49 от RuNTiME » Записан

Любимая игрушка - debugger ...
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #11 : 11-08-2011 08:21 » 

RuNTiME, нет, не обращаются, зачастую это макрос, с каким-нибудь cmpxchg внутри, ну или чем-то чуть более сложным, но без вызова ядра. Вы как-раз привели цитату про "CPU has some sort of atomic instructions".
« Последнее редактирование: 12-08-2011 07:31 от darkelf » Записан
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #12 : 11-08-2011 08:33 » 

Антон (LogRus), Если переходить на конкретный случай, то эта переменная отражает состояние в классте потока. Что - то навроде "Новый", "Запущен", "Приостановлен", "Остановлен". И защищать на запись обязательно т.к. изменять её могут множество потоков, которым требуется управлять данным классом потока. И да, безусловно защищены все вычисления и манипуляции приводящие к изменению этой переменной. Под вопросом только считывание этого состояния без блокирования переменной. Насчет volatile, которая отключает оптимизацию переменной, думаю что побочных эффектов не будет, если защищен весь код, который изменяет эту переменную.
"думаю не будет" и "не будет" это разные вещи, если ты эту переменную читаешь в каком нибуть цикле рабочего потока и в зависимости от значения выходишь из потока или отправляешь его вспячку или еще чего, то ты имеешь все шансы огрести по полной программе, компилятор не сильно в курсе, что ты собираешься её менять, где-то снаружи и имеет полное право нарисовать код который зачитает её 1 раз перед началом цикла, выполнит пару проверок и далее забьёт на неё здоровенный болт и ты можешь хоть как её писать и переписывать в паралельных потоках, сгеренированному коду это будет не особо интерестно

чтоже касается примитивов синхронизации, то лично я предпочитаю использовать spin мьютекс из tbb (и прочие прелести), ребята из intel знают, как правильно строить блокировки Улыбаюсь
Записан

Странно всё это....
RuNTiME
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #13 : 11-08-2011 08:46 » 

darkelf, А так же привели пару фраз: These variables can be used to hold spin locks or SMP-safe reference counters. и If necessary, hardware bus locking is performed to protect the operation. Так что аж 2 вида блокировок используется. Спинлоки - да не требуют вызова кода ядра т.к. представляют собой обычный замкнутый цикл. А вот hardware locking думаешь кто осуществляет?  Улыбаюсь

Антон (LogRus), Я наверное не очень хорошо описал то что происходит. В коде нет глобальной переменной которую можно менять по всей программе. Переменная закрыта в private секции класса Thread и изменяется соответственно только функциями этого класса. Все функции этого класса, которые изменяют значение этой переменной в самом начале получают блокировку мьютекса (получается своеобразная критическая секция).

Вот так выглядит суть:
Код: (C++)
class Thread {
private:
    Mutex _lock;
    int _state;
public:
    void run();
    int getState() const { return _state; }
};

void Thread::run() {
    MutexLocker auto_lock(_lock); // в конструкторе MutexLocker устанавливает блокировку, в деструкторе освобождает.

    _state = 1; // изменяем переменную
}
Записан

Любимая игрушка - debugger ...
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #14 : 11-08-2011 09:14 » 

darkelf, А так же привели пару фраз: These variables can be used to hold spin locks or SMP-safe reference counters. и If necessary, hardware bus locking is performed to protect the operation. Так что аж 2 вида блокировок используется. Спинлоки - да не требуют вызова кода ядра т.к. представляют собой обычный замкнутый цикл. А вот hardware locking думаешь кто осуществляет?  Улыбаюсь
это про то, что atomic_t используется для реализации spinlock-ов и smp reference counter-ов.  А hardware bus locking - это, если не ошибаюсь, в x86-ой архитектуре - префикс команды LOCK.
Записан
RuNTiME
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #15 : 11-08-2011 09:23 » 

darkelf, Да ты прав. Только вот не представляю, каким образом он может обходится без блокировки потока.

PS: Почитал про команду LOCK. Теперь дошло. Окей буду использовать эти функции. Для реализации класса AtomicInt.
« Последнее редактирование: 11-08-2011 09:36 от RuNTiME » Записан

Любимая игрушка - debugger ...
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #16 : 11-08-2011 09:39 » 

Если я правильно помню, то этот самый захват шины должен выполнить запрос на сброс кешей (или соответствующих строк кеша) в других процессорах,  во время записи переменной в память. Таким образом, если потоки с других процессов попытаются прочитать/использовать переменную, им придётся заново вычитывать из памяти уже её новое значение. Сам поток какими-либо службами ОС при этом, имхо, не блокируется, разве что как-то самим процессором, но это уже немного не та блокировка
Записан
Ochkarik
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #17 : 11-08-2011 10:07 » 

простите, просмотрел тему мельком А черт его знает...,
 но пять копеек хочется вставить:
писать СВОЙ класс? а простите зачем, если функции атомарного доступа поддерживаются компилятором?
например, для microsoft-овского cl.exe это _InterlockedIncrement, _InterlockedExchangeAdd, _InterlockedCompareExchange и подобные ей для других - тоже должно быть, искать лень.

PS darkelf, про LOCK и кэш ты меня опередил))) да, все верно.
без префикса LOCK на чтение - там будут чудеса с очередностью записей через кэш.
« Последнее редактирование: 11-08-2011 10:19 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
RuNTiME
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #18 : 11-08-2011 10:16 » 

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

PS: В конце концов почему - то реализован класс atomic в той же STL...
« Последнее редактирование: 11-08-2011 10:18 от RuNTiME » Записан

Любимая игрушка - debugger ...
Ochkarik
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #19 : 11-08-2011 10:20 » 

RuNTiME, разных - это каких?
« Последнее редактирование: 11-08-2011 10:23 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
RuNTiME
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #20 : 11-08-2011 10:23 » 

Ochkarik, А разве у нас есть только компилятор от microsoft? Ну например еще GCC... Или вдруг кому - то вздумается компилить библиотеку интеловским компилятором? А может Borland?
Записан

Любимая игрушка - debugger ...
Ochkarik
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #21 : 11-08-2011 10:39 » 

GCC interlocked http://gcc.gnu.org/onlinedocs/gcc-4.1.0/gcc/Atomic-Builtins.html
Microsoft http://msdn.microsoft.com/en-us/library/26td21ds(VS.71).aspx
Intel http://cache-www.intel.com/cd/00/00/34/76/347603_347603.pdf раздел Lock and Atomic Operation Related Intrinsics(почти microsoft)
все это переопределяется тупыми макросами.
борланд искать лень)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
RuNTiME
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #22 : 11-08-2011 10:49 » 

Ochkarik, За инфу спасибо, но:
1. Подобные махинации с макросами совсем не вписываются в парадигмы ООП
2. Написать класс гораздо проще чем перерывать мануалы всех существующих компиляторов
3. Оборачивая классами различные платформо-зависимые функции, получаешь легко переносимый и читабельный код

PS: Подобные директивы компилятора лучше всего использовать если точно знаешь, что код будет собираться именно этим компилятором и именно на этой платформе.
Записан

Любимая игрушка - debugger ...
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #23 : 11-08-2011 10:52 » 

Ochkarik, Ответ очень прост, код должен компилироваться на разных компиляторах, и даже если использовать условную компиляцию, написание кода превратится в ад.
Ну почему сразу в ад? Можно ведь сделать обёртку и компилировать её по-разному для разных платформ. Все условия препроцессора тогда будут в одном месте (или и вовсе можно иметь один заголовок на всё, и к нему - сколько нужно модулей, реализующих под каждую платформу по-своему, компилирующихся каждый под свою платформу)
Записан
Ochkarik
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #24 : 11-08-2011 11:01 » 

это не махинации) а ООП для этого использовать это... подземный ход через чердак)
и кстати... а кто такой  MutexLocker?
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
RuNTiME
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #25 : 11-08-2011 11:04 » 

Вад,

Цитата
Можно ведь сделать обёртку и компилировать её по-разному для разных платформ.
Так и делаю Улыбаюсь

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

Да и вообще, что мы заговорили о директивах компилятора? Чем оно лучше обертывания обычных системных вызовов?
Записан

Любимая игрушка - debugger ...
Ochkarik
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #26 : 11-08-2011 11:08 » 

Вад,
Цитата
Можно ведь сделать обёртку и компилировать её по-разному для разных платформ.
Так и делаю Улыбаюсь
так  и все так делают)
Цитата
Да и вообще, что мы заговорили о директивах компилятора? Чем оно лучше обертывания обычных системных вызовов?
эх... только тем, что ресурсы на это не тратятся.
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
RuNTiME
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #27 : 11-08-2011 11:18 » 

это не махинации) а ООП для этого использовать это... подземный ход через чердак)
и кстати... а кто такой  MutexLocker?

Почему подземный ход через чердак? Если библиотека полностью ООП, какой смысл в ней использовать такие хаки?

MutexLocker это очень простой класс, который позволяет заблокировать мьютекс при входе в функцию или блок, а потом
автоматически разблокировать его.
Код: (C++)
// И позволяет избежать таких вот косяков:
// как видно мьютекс останется залоченым если условие выполниться
{
    mutex.lock()
    if(<условие>) {
        // какая - то ошибка
        return -1;
    }
    mutex.unlock()
}

// С MutexLocker все будет работать отлично:
{
    MutexLocker __lock(lock);
    if(<условие>) {
        // какая - то ошибка
        return -1;
    }
}
// в любом случае, хоть через return хоть просто выйдя за пределы блока
// мьютекс будет автоматически разблокирован в деструкторе класса MutexLocker

Цитата
эх... только тем, что ресурсы на это не тратятся.
Очень спорный вопрос....
Записан

Любимая игрушка - debugger ...
Ochkarik
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #28 : 11-08-2011 12:01 » 

да нет, я просто офигиваю маленько... в процессоре есть аппаратная команда, специально для этого предназначенная, максимально эффективная, но использовать ее - религия ООП не позволяет...

а код какой то... непонятный) особенно последний блок - ума не приложу что он должен делать)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
RuNTiME
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #29 : 11-08-2011 12:10 » 

Ochkarik,
Цитата
в процессоре есть аппаратная команда...
Да и выше уже обсуждали ряд макросов atomic_* которые как раз и используют эту самую аппаратную команду...

Цитата
а код какой то... непонятный) особенно последний блок - ума не приложу что он должен делать)
А тут сложного ничего нет, создаём экземпляр класса MutexLocker при этом естественно автоматически вызывается его конструктор,
который вызывает mutex.lock() переданного ему мьютекса. Далее когда происходит выход из блока экземпляр класса MutexLocker автоматически
разрушается при этом вызывается его деструктор, который в свою очередь вызывает mutex.unlock().
Записан

Любимая игрушка - debugger ...
PredatorAlpha
Помогающий

ua
Offline Offline

« Ответ #30 : 11-08-2011 12:15 » 

Там используется то, что деструкторы локальных объектов вызываются в любом случае, даже если return где-то в теле или возникло исключение. Очень удобная штука для освобождения ресурсов.
Просто Ochkarik больше на классическом С работает...
Записан
Ochkarik
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #31 : 11-08-2011 12:20 » 

а в каком месте та переменная то стоит, которую синхронизировать надо было?
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
RuNTiME
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #32 : 11-08-2011 12:24 » 

Ochkarik, Тут просто пояснение почему и как работает MutexLocker. Переменную смотри в начале, где я выкладывал код класса Thread.
Записан

Любимая игрушка - debugger ...
Ochkarik
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #33 : 11-08-2011 14:17 » 

я просто за основной алгоритм принял фразу:
"Есть переменная, тип int. Два потока пишут в эту переменную, а третий считывает значение этой переменной."
и для этого - функции ожидания не нужны.

а на самом деле, вам еще и функции ожидания была жизненно необходима?

Просто Ochkarik больше на классическом С работает...
есть немного))))
« Последнее редактирование: 11-08-2011 14:26 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
PredatorAlpha
Помогающий

ua
Offline Offline

« Ответ #34 : 11-08-2011 14:36 » 

Просто Ochkarik больше на классическом С работает...
есть немного))))
Я сам такой...
Embedded-программер..
Записан
RuNTiME
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #35 : 11-08-2011 15:36 » 

Ochkarik,
Цитата
а на самом деле, вам еще и функции ожидания была жизненно необходима?
Изначально мне нужно было только лишь узнать, можно ли безопасно считывать значение этой самой переменной. И я сформулировал только суть. Ну, а раз уж тему развили, почему бы и не по обсуждать связанные с этим проблемы... Улыбаюсь
Записан

Любимая игрушка - debugger ...
Ochkarik
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #36 : 11-08-2011 15:46 » 

тады - ой)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #37 : 12-08-2011 04:22 » 

ну и очередные мои 5 копеек Улыбаюсь
lock не блокирует шину, времена те давно минули
lock блокирует кэш линию

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

PS: а зачем тебе своя реализация всего этого чуда, если есть открытые и быстрые?
PPS: а сравнительные тесты будут?
PPPS: кстати рекомендую использовать названия для классов и методов используемые в tbb и boost::thread - это позволит быстро менять реализацию блокировок в приложении или отдельном классе в зависимости от желания и модели использования конкретного класса
Записан

Странно всё это....
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #38 : 12-08-2011 05:28 » 

пару раз упоминалось использование объектов ядра для синхронизации, но имхо в Париже так уже не носят Улыбаюсь
обычно используется, то что называет futex, собственно реализация мьютекса с использованием асма и есть реализация futex, главный бонус это отсутсвие переключения контекста и отсутсвие объектов ядра, которые как известно имеют тенденцию кончаться в некоторых системах
Прошу прощения, но, imho, asm к mutex-ам/futex-ам имеет опосредованное значение, и, насколько я помню, futex-ом называется один из базовых примитивов синхронизации в linux, который был реализован при переходе с Linuxthreads на NPTL. Кроме того, определённый объект ядра там используется - очередь ожидания, иначе как ядро обеспечит ожидание нескольких потоков (По крайней мере так написано в документе The Native POSIX Thread Library for Linux).
« Последнее редактирование: 12-08-2011 05:38 от darkelf » Записан
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #39 : 12-08-2011 05:39 » 

darkelf, что-то я про это совсем забыл Улыбаюсь вот я раздолбай, давно много потоковые системы не строил
Записан

Странно всё это....
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #40 : 12-08-2011 06:47 » 

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

Собственно, расположив их в разделяемой памяти можно и межпроцессное взаимодействие осуществлять без участия ядра.


Добавлено через 2 минуты и 45 секунд:
darkelf, принцип простой: если не можешь захватить, то выполни yield() и потом еще раз попробуешь. Никаких дополнительных очередей - все в рамках обычного планировщика.
« Последнее редактирование: 12-08-2011 06:50 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
RuNTiME
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #41 : 12-08-2011 07:01 » 

PS: а зачем тебе своя реализация всего этого чуда, если есть открытые и быстрые?
По двум причинам:
Первая и основная углубленное изучение многопоточного программирования (ну хочется мне).
А вторая банальная - свести к минимуму кол-во зависимостей.

PPS: а сравнительные тесты будут?
Сравнивать пока нечего да и основные задачи библиотеки не реализация классов для написания многопоточных приложений.

PPPS: кстати рекомендую использовать названия для классов и методов используемые в tbb и boost::thread - это позволит быстро менять реализацию блокировок в приложении или отдельном классе в зависимости от желания и модели использования конкретного класса
За наводку на tbb спасибо. Вчера еще скачал эту библиотеку. Будет с чего брать пример.
boost - очень уж громоздок если использовать его только для запуска потоков
Записан

Любимая игрушка - debugger ...
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #42 : 12-08-2011 07:28 » 

Добавлено через 2 минуты и 45 секунд:
darkelf, принцип простой: если не можешь захватить, то выполни yield() и потом еще раз попробуешь. Никаких дополнительных очередей - все в рамках обычного планировщика.
Imho, yield(), требует как входа в ядро, так и использования очереди - в случае, если есть более высокоприоритетные процессы/потоки текущий процесс надо будет приостановить, соответственно, поставить в очередь ожидания и выполнить переключение контекста на более приоритетный.
Записан
Ochkarik
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #43 : 12-08-2011 07:33 » 

RuNTiME, может вы целиком задачу опишите, а то разговор пошел на пустом месте)
задач много, способов реализации тоже) щас каждый выложит свои задачи многопоточности и соответствующие решения и будет каша)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #44 : 12-08-2011 07:39 » 

darkelf, для проверки и захвата мютекса входить в ядро не нужно - это и есть преимущество. А вот в случае неудачи захвата по любому придется ожидать.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #45 : 12-08-2011 07:46 » 

darkelf, для проверки и захвата мютекса входить в ядро не нужно - это и есть преимущество.
Про это я знаю.

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

ru
Offline Offline
Пол: Мужской

« Ответ #46 : 12-08-2011 07:55 » 

Ochkarik, На вопрос для которого создавалась эта тема я получил ответ, получил даже намного больше. Общая задача это написание библиотеки сильно упрощающей разработку Web приложений на C++. Это не производственная задача, пишу в своё удовольствие (так что сильно не пинайте).  Улыбаюсь Если кому - то это интересно, могу создать отдельную тему и можем обсудить целесообразность всего этого.
Записан

Любимая игрушка - debugger ...
Страниц: 1 2 [Все]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines