Russian Qt Forum
Ноябрь 23, 2024, 08:47 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2] 3   Вниз
  Печать  
Автор Тема: Помогите понять как работают мьютексы в Qt.  (Прочитано 24049 раз)
BRE
Гость
« Ответ #15 : Март 29, 2012, 17:04 »

Примечание: использование QWaitCondition и QSemaphore часто равноценно.
К сожалению нет.
При использовании условных переменных ядро разбудит одну из нитей (ожидающих эту переменную) вне очереди, а при семафорах нитка проснется и продолжит выполнение, только дождавшись своей очереди.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #16 : Март 29, 2012, 17:13 »

К сожалению нет.
При использовании условных переменных ядро разбудит одну из нитей (ожидающих эту переменную) вне очереди, а при семафорах нитка проснется и продолжит выполнение, только дождавшись своей очереди.
Несколько ниток ждут на одном семафоре. Кто-то просигналил, семафор открылся, и одна из ниток его захватила. Чем здесь WaitCondition выгоднее?
Записан
BRE
Гость
« Ответ #17 : Март 29, 2012, 17:26 »

У процесса 10 ниток. Пусть они выполняются в порядке их номеров.
Нитки 1, 2, 3 ждут на условной переменной, нитка 4 делает wakeOne, ядро может разбудить одну из ниток 1-3.
При семафоре: сначала отработают нитки 5-10, и только потом нитка 1 получит управление и захватит семафор.
« Последнее редактирование: Март 29, 2012, 17:33 от BRE » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #18 : Март 29, 2012, 18:27 »

У процесса 10 ниток. Пусть они выполняются в порядке их номеров.
Нитки 1, 2, 3 ждут на условной переменной, нитка 4 делает wakeOne, ядро может разбудить одну из ниток 1-3.
При семафоре: сначала отработают нитки 5-10, и только потом нитка 1 получит управление и захватит семафор.
Т.е. нитка(и) ждущая на семафоре проснется только тогда когда ОС выделит ей квант времени? А на условной переменной нет? Никогда не слышал о таком, дайте линк. Спасибо

Также уточните о чем Вы говорите: о системных вызовах sem_wait и pthread_cond_wait или как? Потому что в Qt оба реализованы на pthread_cond_wait, и с этой точки зрения разницы нет.

Спускаясь на землю - семафор примитивнее, но часто именно эта простота и нужна. Число побудок равно числу просыпающихся - и все дела. Идеально для создатель-потребитель. WaitCondition хитрее, побудка может и не иметь эффекта. Но зато надо думать "хз а не проскочит ли". Зачем усложнять когда семафор делает все что нужно?
« Последнее редактирование: Март 29, 2012, 18:31 от Igors » Записан
BRE
Гость
« Ответ #19 : Март 29, 2012, 19:20 »

Т.е. нитка(и) ждущая на семафоре проснется только тогда когда ОС выделит ей квант времени? А на условной переменной нет? Никогда не слышал о таком, дайте линк. Спасибо
А ты поищи сам.
Я не все читаю в интернете и не всегда могу точно вспомнить источник. Это могла быть печатная статья, книга или исходники ядра linux.

Также уточните о чем Вы говорите: о системных вызовах sem_wait и pthread_cond_wait или как? Потому что в Qt оба реализованы на pthread_cond_wait, и с этой точки зрения разницы нет.
Я говорил про pthread_cond_xxx и sem_xx. Если в Qt и QWaitCondition и QSemaphore выполнен на условных переменных, то разницы конечно нет.

Но зато надо думать "хз а не проскочит ли".
Кто и куда не проскочит?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #20 : Март 29, 2012, 20:29 »

Кто и куда не проскочит?
Вот пример из букваря (только выкинул sleep)
Код
C++ (Qt)
// "потребитель"
forever {
    mutex.lock();
    keyPressed.wait(&mutex);
    ++count;
    mutex.unlock();
 
    do_something();
 
    mutex.lock();
    --count;
    mutex.unlock();
}
 
// производитель
forever {
    getchar();
 
    mutex.lock();
    keyPressed.wakeAll();
    mutex.unlock();
}
Пусть потребитель увлечен тем do_something, на кеуpressed (он же condition) никто не ждет. Значит эффект wakeAll нулевой. Шустрый пользователь успевает ввести еще getchar - вот и "проскочило"

Кроме того, я лично недопонимаю один момент. С точки зрения "ожидающего побудки" все ясно
Код
C++ (Qt)
    mutex.lock();             // захватил мутекс
    keyPressed.wait(&mutex);  // освобождаю и жду
    ++count;                // здесь если я получил управление, то я же и владею мутексом
 

А вот что с будящим....
Код
C++ (Qt)
   mutex.lock();     // захватил мутекс
   keyPressed.wakeOne();   // бужу/будю
   mutex.unlock();        // так чей же мутекс??? Мой или того кто проснулся?
 

Объясните. Спасибо
Записан
Bepec
Гость
« Ответ #21 : Март 29, 2012, 20:46 »

Помоему ваш пример насчёт нажатия кнопки ээээ... Как бы сказать - высосан из пальца.


Насчёт мутексов / разблокировки - я твой пример не понимаю.
Если разные потоки, то это будут разные мутексы. И ваше wakeAll не будет иметь эффекта.

Если один поток, то там (в простейшей ситуации) будет 1 мьютекс, который собственно лочится/анлочится.


Если честно не понимаю вообще вашего примера. WaitCondition ждёт пробуждения. Функция do_something() не должна являться рекурсивной, иначе теряется смысл WaitCondition.

WakeCondition (по моему мнению) идеальный вариант сигнала обработки данных.

Засыпаем.
     Данные добавляются.
Побудка.
    Просыпаемся. Обрабатываем всю пришедшую информацию.
Засыпаем.

А насчёт использовать его аналогично обычному сигналу (тот же keyPressed) помоему извращение. Как Семафор в качестве переменной int к примеру Подмигивающий
Записан
BRE
Гость
« Ответ #22 : Март 29, 2012, 22:22 »

Пусть потребитель увлечен тем do_something, на кеуpressed (он же condition) никто не ждет. Значит эффект wakeAll нулевой. Шустрый пользователь успевает ввести еще getchar - вот и "проскочило"
Так очереди уже изобрели.
 
так чей же мутекс??? Мой или того кто проснулся?
Еще никто не проснулся, нитка с wait отметилась как готовая к исполнению, но она не проснется пока ты не освободишь мьютекс.

Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #23 : Март 30, 2012, 00:47 »

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

WakeCondition (по моему мнению) идеальный вариант сигнала обработки данных.
Засыпаем.
     Данные добавляются.
Побудка.
    Просыпаемся. Обрабатываем всю пришедшую информацию.
Засыпаем.
Это как раз сценарий семафора  - мы всегда можем спокойно положиться на него. В случае waitCondition надо считаться с тем что побудка может прийти когда мы заняты обработкой. Это может быть и выгоднее
Код
C++ (Qt)
// обработчик
while (true) {
mutex.lock();   // захватили мутекс - будить никто не сможет (пока)
 
if (!data.size())    // если данных еще нет - освобождаем мутекс и ждем побудки
 myCondition.wait(&mutex);
 
// теперь мутекс опять наш
int val = data.takeAt(0);  // отхватили кусок данных под защитой
mutex.unlock();   // освободили данные
 
DoCalc(val);  // обрабатываем
}  
 


Еще никто не проснулся, нитка с wait отметилась как готовая к исполнению, но она не проснется пока ты не освободишь мьютекс.
Ну да, по-другому не видно как. Но смущает что в манах это "не звучит"   Улыбающийся
Записан
Bepec
Гость
« Ответ #24 : Март 30, 2012, 07:02 »

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

Причём в моих случаях, WaitCondition выгоднее семафора и "проще".

PS хотя кто знает, мб я его использую не так, как задумывали разработчики,но "это работает".
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #25 : Март 30, 2012, 13:30 »

Причём в моих случаях, WaitCondition выгоднее семафора и "проще".
Как и наоборот  Улыбающийся  Вот задачка "проще некуда" - одна нитка читает консольный символ, другая печатает просто "pressed". Реализация любителя семафоров
Код
C++ (Qt)
// читатель
whle (true) {
getchar();    // ждем символа
theSemaphore.release(); // открываем семафор
}
 
// писвтель
whle (true) {
theSemaphore.acquire();    // ждем на семафоре
printf("pressed");  // печатаем
}
 
А как это сделать на QWaitCondition ?
Записан
Bepec
Гость
« Ответ #26 : Март 30, 2012, 14:15 »

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


Скажем проще - в ситуации:
Неизвестно когда/что/кто/сколько добавит и надо обработать - waitCondition полезно. (обработка всех добавленных данных и опять спячка)

А когда:
Ожидаем действия пользователя и вызываем адекватную реакцию - тут уже семафоры/сигналы.

WaitCondition не позиционируется как сигнал/система реального времени (мб перемудрил с определением). Он не даст адекватной быстрой реакции в ваших примерах.

А вот в случае аля "слушаем 500 устройств, возможно кто-то что-то пришлёт, а присланное и разобрать надо неизвестной длины" - тогда уже wait рулит Подмигивающий

PS возможно их использование и как аналогов, но они разного принципа Подмигивающий
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #27 : Март 30, 2012, 14:41 »

Реализация с семафором проста и понятна - по 2 строчки на нитку. А что с WaitCondition? С высказанными общими соображениями я вполне согласен, ну а делать-то что? Приводим псевдокод или признаем что такую мелочь оказывается сложно сделать на  condition  Улыбающийся
Записан
BRE
Гость
« Ответ #28 : Март 30, 2012, 15:27 »

Реализация с семафором проста и понятна - по 2 строчки на нитку. А что с WaitCondition? С высказанными общими соображениями я вполне согласен, ну а делать-то что? Приводим псевдокод или признаем что такую мелочь оказывается сложно сделать на  condition  Улыбающийся
Ну если QSemaphore сделан на QWaitCondition, то можно развернуть методы семафора. Улыбающийся

Посмотрел что сейчас делается на этом фронте...
Для систем с многоядерными процессорами есть один момент. Условная переменная имеет возможность подготовить к пробуждению одну нитку из нескольких ждущих, а с семафорами похуже. Ядро готовит к пробуждению все нитки ждущие на семафоре, что бы они в конкурентной борьбе могли захватить ресурс. Т.е. ждут пять ниток, появился один ресурс, все проснулись, самая быстрая его захватили, все остальные проверили и заснули дальше.
Записан
Bepec
Гость
« Ответ #29 : Март 30, 2012, 17:40 »

Igors,  вы мне предлагаете выложить вам вариант костыля использования QWaitCondition в роли семафора. Улыбающийся

А выложите-ка вы мне сначала пример реализации "проскакивающего" пробуждения (вы ведь ранее его сами приводили и недоумевали), используя Семафор заместо WaitCondition.

PS вот сейчас вы конкретно неправильно ставите вопрос. Это разные классы с почти одинаковыми возможностями. Но только почти.

Записан
Страниц: 1 [2] 3   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.446 секунд. Запросов: 23.