Потоки запускаются, когда планировщик приступает к их выполнению.
Способ, которым один поток 2 должен работать быстро: когда поток 1 сигнализирует, что поток 2 просыпается (и в вашем случае много раз до того, как на самом деле это делает поток 2), все потоки, ожидающие переменную условия, должны бороться за блокировку, когда планировщик запускает их. В вашем примере, я уверен, что планировщик никогда не попадет в поток 2 до его завершения. Хорошая ставка в том, что ваш временной интервал составляет 1 мс.
Способ, которым два потока 2 не работают быстро: поток 1 сигнализирует о потоке 2, но когда поток 2 пробуждается, поток 1 все еще блокируется (либо потому, что поток 1 находится в более позднем цикле, либо потому, что поток 2 немедленно проснулся, а поток 1 имеет мьютекс заблокирован до того, как поток 1 вызвал cond_signal), поэтому поток 2 снова переходит в спящий режим в качестве официанта мьютекса.
В качестве примера все еще предполагается, что поток 2 является ожидающим потоком.
Предположим, вы хотите, чтобы поток 2 немедленно проснулся ... AFAIK, вы ничего не можете сделать.
Если вы действительно хотели, чтобы поток 1 остановился после сигнализации, и вы все еще хотели использовать pthread_cond (есть и другие более быстрые способы!), Вы могли бы разблокировать мьютекс перед передачей ( это позволило, я думаю, ) и затем вызовите sched_yield () или nanosleep ({0,0}) сразу после сигнала. Плохо для производительности, потому что поток 1 просто помещает себя в конец строки потоков (с тем же приоритетом), ожидающих запуска. Это увеличит ваше отношение переключений контекста к времени выполнения. Это также плохо из-за дополнительной разблокировки / блокировки, которую вы должны сделать. Помимо всего этого, поток 1 может снова проснуться, прежде чем поток 2! Вы должны будете использовать цикл, продолжать сигнализировать и уступать, пока этот чертов поток 2 не сделает свою работу! Klunky!
Кстати, моя интерпретация volatile заключается в том, что он сообщает компилятору, что переменная, как ожидается, изменится в любое время. Эта переменная была бы плохой для копирования в регистр в начале функции по соображениям производительности. Компилятор довольно хорошо знает, какие переменные могут это делать, но время от времени он допускает ошибку. Я бы сказал, что когда оптимизация включена, volatile может иметь эффект, если gcc кэширует какие-либо общие переменные в регистрах. Я не знаю, кэширует ли gcc глобалы в регистрах.
веселит.