Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Способы синхронизации

36K
21 января 2010 года
sstorm
55 / / 25.03.2009
Здравствуйте. Прошу прощения за столь абстрактное название темы. Но что спросить конкретного не знаю, однако чувствую, что мне не хватает знаний для своей задачи.
Для синхронизации я сейчас использую мьютексы, причём, фактически, делая из них критические секции. Не всегда это удобно, поэтому хотел бы спросить, а какие приёмы используете вы для синхронизации? (какие парадигмы, классы...?) Если есть возможность, то прямо код можно написать в пример. Буду рад также ссылкам, особенно на русском
Страницы:
34K
21 января 2010 года
muturgan
96 / / 01.10.2009
Цитата: sstorm
Для синхронизации я сейчас использую мьютексы, причём, фактически, делая из них критические секции.


Из мьютексов сделать критические секции - это сильно :) Какая задача у Вас? Универсальный способ синхронизации Вам вряд ли кто-то подскажет.

5
21 января 2010 года
hardcase
4.5K / / 09.08.2005
Цитата: muturgan
Универсальный способ синхронизации Вам вряд ли кто-то подскажет.


Семафоры - наше фсе. Для блокировки читателей-писателей - ReaderWriterLockSlim.

36K
21 января 2010 года
sstorm
55 / / 25.03.2009
под критической секцией я понимал что-то такое:
mutex mt;
......

 
Код:
bool hashTable::didChange(char last, char& inMas) {
    mutex::scoped_lock scoped_lock(mt);
    if (last==inMas) {
        inMas++;
        return false;
    } else {
        return true;
    }
}


функция является критической секцией т.к. туда не зайдут 2 потока одновременно. Объект scoped_lock уничтожается по выходу из блока, снимая мьютекс.


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

поискать страницу в кэше.
Если есть - вернуть её.
Если нет - вытолкнуть какую-то ненужную страницу, загрузить нужную и вернуть.

И проблема:
если 2 потока одновременно просят одну и ту же страницу и выполнение идёт так:
ищет 1ый - не находит. прерывание. Ищет второй - не находит. Выгружает какую-то страницу, загружает нужную - возвращает ссылку на неё. прерывание. Первый выгружает какую-то страницу, загружает нужную (хотя она уже есть в памяти в другом месте), возвращает ссылку на неё.
Даже уж не говоря о том, что если потоки планируют не только читать, но и писать в страницу, то это приведёт к несохранению каких-то данных, так и просто ну зачем в кэше хранить копии...
36K
21 января 2010 года
sstorm
55 / / 25.03.2009
Вот и прошу каких-то ещё идей, как сделать синхронизацию, Может, какой-то класс, который позволит какой-то блок операций осуществить атомарно. (типа раз первая операция выполнилась, то пока последняя не выполнится, прерываний не будет). Ну или ещё что-то подобное. мне просто варианты...
253
21 января 2010 года
Proger_XP
1.5K / / 07.08.2004
В WinAPI есть функции для работы с критическими секциями, например, Initialize/Enter/LeaveCriticalSection. Они как раз и защищают одинаковый участок кода от выполнения двумя потоками одновременно.
36K
21 января 2010 года
sstorm
55 / / 25.03.2009
Да. Только код должен быть кроссплатформенным, поэтому винапи нельзя использовать. Пока остановилмя на бусте, но русской документации по потокам найти не могу. Странно, но в инете из русского только про boost::graph :(
36K
21 января 2010 года
sstorm
55 / / 25.03.2009
Цитата: hardcase
Семафоры - наше фсе. Для блокировки читателей-писателей - ReaderWriterLockSlim.



это .net :(

253
21 января 2010 года
Proger_XP
1.5K / / 07.08.2004
API семофоров есть с Win95, но раз его нельзя использовать, то и они не покатят.
36K
21 января 2010 года
sstorm
55 / / 25.03.2009
Из того, что я нарыл в сети понял, что boost является едва ли не единственным кроссплатформенным вариантом. Но у меня есть проблемы с английским языком, поэтому кроме мьютексов я оттуда немногое понял...
В принципе "мьютекс может всё", поэтому любую стратегию я реализию с их помощью, вероятно. но всё-таки есть загвоздка одна. Мне нужны какие-то способы, чтобы один из потоков стоял на месте и ждал, пока другой поток дойдёт до определённой строчки
253
21 января 2010 года
Proger_XP
1.5K / / 07.08.2004
Ну, сделай какую-нибудь глобальную переменную (процесса) типа bool и в цикле ждущего потока просто делай while (locked) { sleep(10); }
36K
21 января 2010 года
sstorm
55 / / 25.03.2009
Я так и делал, чтобы проверить, нет ли косяков в других местах. но теперь хочется как-то сделать по-нормальному. Если бы я хотя бы был уверен в том, вто в момент, когда поток спит на sleep'е, то процессорное время тратится на другие потоки, а не "ничегонеделает" на этом.

+Sleep() определён в windows.h, что опять же не подходит...


Я не очень понимаю, почему нет комментариев к каждому методу буста. По названием неочевидно...по крайней мере мне
253
21 января 2010 года
Proger_XP
1.5K / / 07.08.2004
Sleep() насколько я понимаю замораживает поток, а не просто гоняет цикл пока не стукнет N мсек. Правда, как это может делаться кросс-платформенно я не знаю.
3
21 января 2010 года
Green
4.8K / / 20.01.2000
Цитата: Proger_XP
Ну, сделай какую-нибудь глобальную переменную (процесса) типа bool и в цикле ждущего потока просто делай while (locked) { sleep(10); }


жжешь...
руки бы поотрывал

36K
21 января 2010 года
sstorm
55 / / 25.03.2009
Green, посоветуйте лучше что-нибудь мне:)
253
21 января 2010 года
Proger_XP
1.5K / / 07.08.2004
Да, я целиком и полностью согласен, что глобальные переменные - зло, но лучшего на ум ничего не пришло.

2sstorm
Вообще, я бы пока не заморачивался с кросс-платформенностью. Сделай абстрактный класс (назови, например, Synchronizer) и наследуй от него WinSynchronizer, в котором используй API. Когда (и если) дело дойдет до других ОС, то сделаешь прочие классы и все.
41K
21 января 2010 года
gaga
44 / / 22.07.2009
А pthread разве нет под винду? Там и мутексы, и семафоры, и условные переменные вроде есть.
3
21 января 2010 года
Green
4.8K / / 20.01.2000
Цитата: sstorm
Green, посоветуйте лучше что-нибудь мне:)


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

Вооружившись английским идем в Google ищем по ключу: multi-threading libraries
От себя отмечу boost:thread (http://www.boost.org/doc/libs/1_41_0/doc/html/thread.html)
и pthreads (http://ru.wikipedia.org/wiki/POSIX_Threads).

3
21 января 2010 года
Green
4.8K / / 20.01.2000
Цитата: Proger_XP
Да, я целиком и полностью согласен, что глобальные переменные - зло, но лучшего на ум ничего не пришло.

2sstorm
Вообще, я бы пока не заморачивался с кросс-платформенностью. Сделай абстрактный класс (назови, например, Synchronizer) и наследуй от него WinSynchronizer, в котором используй API. Когда (и если) дело дойдет до других ОС, то сделаешь прочие классы и все.



Да здесь глобальная - переменная пушистый кролик, по сравнению с циклом.

253
21 января 2010 года
Proger_XP
1.5K / / 07.08.2004
Цитата:
Да здесь глобальная - переменная пушистый кролик, по сравнению с циклом.


В том смысле, что нужно использовать события (семафоры и пр.), если можно?

46K
22 января 2010 года
Mukhitov
15 / / 26.04.2009
Хм. Читай документацию по операционным системам, и пиши свои классы для синхронизации.
3
22 января 2010 года
Green
4.8K / / 20.01.2000
Цитата: Mukhitov
Хм. Читай документацию по операционным системам, и пиши свои классы для синхронизации.


А ещё лучше, пиши свои операционные системы. :D

Ты сам придумал такой дельный совет или прочитал в документации по операционным системам?

36K
22 января 2010 года
sstorm
55 / / 25.03.2009
Цитата: Green



Вот в коде автодополнение указывает на то, что у mutex есть метод getEvent, к примеру. В этой документации, что по ссылке выше, нет ни слова об этом методе. А судя по названию, мне что-т подобное (со словм event) и нужно

41K
22 января 2010 года
gaga
44 / / 22.07.2009
Я так и не понял, чем мутексы плохи в твоем случае. Вот обычная критическая функция:
 
Код:
int CriticalFunction(...) {
  static pthread_mutex_t mt = PTHREAD_MUTEX_INITIALIZER;
  pthread_mutex_lock(&mt);  // вход в секцию
  ...
  pthread_mutex_unlock(&mt); //выход из секции
  return 0;
}

Если не хочется блокироваться на время ожидания освобождения мутекса:
Код:
int CriticalFunction(...) {
  static pthread_mutex_t mt = PTHREAD_MUTEX_INITIALIZER;
  if ( pthread_mutex_trylock(&mt) == EBUSY ) { // другой поток уже в секции
    return EBUSY;
  } else { // входим в секцию
    ...
  }
  pthread_mutex_unlock();
  return 0;
}

int main(void) {
  while( CriticalFunction() == EBUSY ) {
    DoSomeJobWhileWaiting();
  }
    // по выходу из цикла имеем выполнившуюся один раз функцию
}
46K
22 января 2010 года
Mukhitov
15 / / 26.04.2009
Цитата: Green
А ещё лучше, пиши свои операционные системы. :D

Ты сам придумал такой дельный совет или прочитал в документации по операционным системам?



За исключением мьютексов все остальные методы синхронизации(семафоры, события, сообщения и т.д.) средства операционной операционной системы.

253
22 января 2010 года
Proger_XP
1.5K / / 07.08.2004
Цитата:
операционной операционной системы


...неоперационной операционной системы...

14
22 января 2010 года
Phodopus
3.3K / / 19.06.2008
Цитата: Mukhitov
За исключением мьютексов все остальные методы синхронизации(семафоры, события, сообщения и т.д.) средства операционной операционной системы.


А мютексы-то тогда что? Десница божья? :eek:

1.9K
22 января 2010 года
GreenRiver
451 / / 20.07.2008
Цитата: sstorm
Из того, что я нарыл в сети понял, что boost является едва ли не единственным кроссплатформенным вариантом.


Почему же единственным??? А как же Qt?
Если ещё не очень много завязано на boost - советую присмотреться к ней.

63
22 января 2010 года
Zorkus
2.6K / / 04.11.2006
Холивара все равно тут не получится нормального.
Средства операционной системы... не нужно использовать напрямую, кроме минимально необходимого. А вот знать очень полезно.
36K
22 января 2010 года
sstorm
55 / / 25.03.2009
Ну вот да. Вторым вариантом из найдённых и было qt, но буст уже был, в отличии от qt, это и определило. (пишу я в винде)

По вашей ссылке, GreenRiver, даже русские маны. Обидно, что я сразу её не выбрал. Теперь надо пересогласовывать будет и переписывать, если в ближайшие пару дней не смогу до"понять" буст
3
22 января 2010 года
Green
4.8K / / 20.01.2000
Цитата: sstorm
Ну вот да. Вторым вариантом из найдённых и было qt, но буст уже был, в отличии от qt, это и определило. (пишу я в винде)

По вашей ссылке, GreenRiver, даже русские маны. Обидно, что я сразу её не выбрал. Теперь надо пересогласовывать будет и переписывать, если в ближайшие пару дней не смогу до"понять" буст


М-да... из пушки по воробьям...

36K
22 января 2010 года
sstorm
55 / / 25.03.2009
Как раз я думаю, что буст компактный, в отличии от кутэ, которая действительно здоровая махина-пушка. Или вы не то имели в виду?
1.9K
22 января 2010 года
GreenRiver
451 / / 20.07.2008
Цитата: Green
М-да... из пушки по воробьям...


Почему по воробьям? Если нужна кроссплатформенность, то Qt довольно хороший выбор (особенно если понадобится GUI). Или я что-то не так понял?

P.S. Похоже холивар все-таки получится ;)

253
22 января 2010 года
Proger_XP
1.5K / / 07.08.2004
Гм, я понимаю, что Green'у сейчас надоедают нубы в моем лице, но может мне тоже можно ответить? :)
Цитата:

[quote]Да здесь глобальная переменная - пушистый кролик, по сравнению с циклом.


В том смысле, что нужно использовать события (семафоры и пр.), если можно?
[/quote]

36K
22 января 2010 года
sstorm
55 / / 25.03.2009
Этот холивар интересен в плане перечисления преимуществ, так что полезен для меня.

зы: если уж так хорошо все тут собрались, то можно попросить пояснить один момент из кутяшных доков:
Обратите внимание на то, что классы синхронизации Qt зависят от использования правильно выровненных (properly aligned) указателей. Например, вы не можете использовать упакованные классы вместе с MSVC.
В принципе я догадываюсь, что речь о выравнивании по границе 4 байт. Но даже если в этом я прав, возникают 2 вопроса:
1) в x64 граница тоже 4 байта?
2) Как определить какой класс является "упакованным", и почему нельзя использовать их в студии? А если юзать нетбинс, то становится возможным их использование?
36K
22 января 2010 года
sstorm
55 / / 25.03.2009
Proger_XP, просто процессорное время убивается на цикл зря. Не должен процессор крутиться в нём, даже если принять во внимание, что 10 милисекунд простоя по Sleep'у он тратит на полезные действия. Всё равно если ему предстоит ждать секунду, то совершится много ненужных проверок условия цикла. А если же мьютексы отпускаются быстро, то зачем ждать 10 милисекунд, вдруг оно за 1 милисекунду способно пойти дальше? Поэтому там требуется какой-то механизм оповещений... "пробуждений ото сна". Чтобы не спящий проверяд. не пора ли проснуться, а поток, закончивший своё (чёрное) дело, будил как-то
3
23 января 2010 года
Green
4.8K / / 20.01.2000
Цитата: sstorm
Как раз я думаю, что буст компактный, в отличии от кутэ, которая действительно здоровая махина-пушка. Или вы не то имели в виду?



Цитата: GreenRiver
Почему по воробьям? Если нужна кроссплатформенность, то Qt довольно хороший выбор (особенно если понадобится GUI). Или я что-то не так понял?



Использовать Qt ради одной синхронизации - это и есть из пушки...
Qt - это в первую очередь UI framework.
Вы же не покупаете автомобиль ради пепельницы?

3
23 января 2010 года
Green
4.8K / / 20.01.2000
Цитата: Proger_XP
Гм, я понимаю, что Green'у сейчас надоедают нубы в моем лице, но может мне тоже можно ответить? :)



Ну sstorm тебе все уже доходчиво объяснил.
Добавлю только, что объекты синхронизации для того и существуют, чтоб их использовать для синхронизации, и не "когда можно", а всегда, когда есть необходимость в синхронизации.

253
23 января 2010 года
Proger_XP
1.5K / / 07.08.2004
Цитата:
Ну sstorm тебе все уже доходчиво объяснил.


Понял, спасибо.

36K
23 января 2010 года
sstorm
55 / / 25.03.2009
Green, ну тогда я согласен с тем, что кутэ - пушка для этой задачи, т.к. визуальность не предполагается, но помимо тех 2 вопросов пятью постами выше про кутэ у меня к вам ещё вопросы:). Конечно, неловко за клянченье информации, но всё равно:
1. буст всё равно довольно объёмен. Но больше мне в нём не нравится даже то, что помимо каких-то хедерсов он ещё потребовал lib'ы. Я что-то не так делал и этого можно было избежать? А если избежать нельзя, то это всё равно пушка, хоть и меньше размером.
2. Каким средством бы воспользовались вы? И если это буст, то каким образом нашли бы документацию к некоторым методам (скажем, mutex.getEvent()), если этого нет ни на boost.org, ни внутри исходников даже комментов
41K
23 января 2010 года
gaga
44 / / 22.07.2009
А я так и не понял, чем плохи pthreads. Объясните, если не сложно.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог