Условное ожидание - PullRequest
       8

Условное ожидание

4 голосов
/ 18 октября 2010

При использовании boost::conditional_variable, ACE_Conditional или напрямую pthread_cond_wait существуют ли какие-либо издержки для самого ожидания? Это более конкретные проблемы, которые могут быть проблемы:

  1. После того, как ожидающий поток не запланирован, будет ли он запланирован назад до истечения срока ожидания, а затем снова не запланирован или останется незапланированным, пока не будет подан сигнал?
  2. wait периодически получает мьютекс? В этом случае, я думаю, что каждая итерация тратит некоторое время процессора на системные вызовы для блокировки и освобождения мьютекса. Это то же самое, что постоянно приобретать и освобождать мьютекс?
  3. Кроме того, сколько времени проходит между сигналом и возвратом из wait?

Afaik, при использовании семафоров скорость отклика на получение вызовов зависит от размера временного интервала планировщика. Как это работает в pthread_cond_wait? Я предполагаю, что это зависит от платформы. Меня больше интересует Linux, но если кто-то знает, как он работает на других платформах, он тоже поможет.

И еще один вопрос: есть ли дополнительные системные ресурсы, выделенные для каждого условия? Я не буду создавать 30000 мьютексов в своем коде, но стоит ли мне беспокоиться о 30000 условных выражениях, которые используют один и тот же мьютекс?

Ответы [ 2 ]

6 голосов
/ 19 октября 2010

Вот что написано на справочной странице pthread_cond:

pthread_cond_wait атомно разблокирует мьютекс и ожидает сигнала условной переменной cond. Выполнение потока приостанавливается, и не использует процессорное время , пока не будет передана переменная условия.

Итак, отсюда я бы ответил на следующие вопросы:

  1. Ожидающий поток не будет запланирован назад до того, как ожидание было сигнализировано или отменено.
  2. Нет периодических приобретений мьютекса. Мьютекс восстанавливается только один раз до возвращения ожидания.
  3. Время, которое проходит между сигналом и возвратом ожидания, аналогично времени планирования потока из-за освобождения мьютекса.

Что касается ресурсов, на той же справочной странице:

В реализации LinuxThreads никакие ресурсы не связаны с переменными условия , таким образом, pthread_cond_destroy фактически ничего не делает, кроме проверки того, что условие не имеет ожидающих потоков.

Обновление: Я копался в источниках функций pthread_cond_ * и поведение выглядит следующим образом:

  1. Все условные выражения pthread в Linux реализованы с использованием futex .
  2. Когда поток вызывает wait, он приостанавливается и не планируется. Идентификатор потока вставляется в конец списка ожидающих потоков.
  3. Когда поток вызывает signal, поток во главе списка запланирован назад. Таким образом, пробуждение так же эффективно, как и планировщик, ресурсы ОС не расходуются, и единственные накладные расходы памяти - это размер списка ожидания (см. futex_wake функция).
1 голос
/ 18 октября 2010

Вы должны вызывать pthread_cond_wait, только если переменная уже находится в «неправильном» состоянии. Поскольку он всегда ожидает, всегда есть издержки, связанные с переводом текущего потока в спящий режим и переключением.

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

30000 мьютексов не должно быть проблемой, но некоторые ОС могут иметь проблемы с 30000 спящими потоками.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...