Поток ожидает сигнала, но не получает его из-за блокировки мьютекса

Итак, я делаю программу с одним основным потоком (мой основной), который создает второй. Второй должен дождаться сигнала и запустить его. Мэйн конечно ждет присоединения.

У меня проблема с пониманием того, как мой main может блокировать мьютекс, а затем мой поток также заблокирует его и будет ждать сигнала. Я имею в виду, что это «руководство», которое все дают о том, как это делать, но я не понимаю, как это работает. Так как мьютекс блокируется при основной блокировке, поток всегда будет переходить к заблокированному отключенному каналу и ждать, пока мьютекс не будет разблокирован, нет? Таким образом, сигнал будет отправлен до того, как поток получит мьютекс и заблокируется в ожидании (поэтому он никогда не будет разбужен). Но опять же, необходимо заблокировать мьютекс, чтобы дождаться переменной ... Помогите пожалуйста. Это код, он создает цикл, потому что функция потока блокируется в ожидании ..

static pthread_mutex_t mtx;
pthread_cond_t cond;

void *threadfunction(void* arg){
    pthread_mutex_lock(&mtx);
    pthread_cond_wait(&cond,&mtx);
    pthread_mutex_unlock(&mtx);
}

int main(void){
    pthread_mutex_init(&mtx,NULL);
    pthread_cond_init(&cond,NULL);

    pthread_t tthread;
    pthread_mutex_lock(&mtx);

    pthread_create(&tthread,NULL,threadfunction,NULL);

    pthread_cond_signal(&cond);

    pthread_mutex_unlock(&mtx);

    pthread_join(tthread,NULL);
}

person JamesTheProg    schedule 15.06.2020    source источник


Ответы (1)


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

Сценарий для переменных условия состоит в том, что когда потоку нужно дождаться выполнения условия, он блокирует мьютекс и вызывает wait. Это освободит мьютекс, чтобы другие потоки могли войти в свои критические секции, изменить условия и signal, чтобы ожидающие потоки могли пробудиться.

В вашем примере вы создаете поток, когда мьютекс уже заблокирован, поэтому у потока нет шансов передать первую блокировку. Это означает, что когда вы сигнализировали потоку, он не ждал.

person Burak Serdar    schedule 15.06.2020
comment
Я знаю, как это работает. Я не понимаю: основные блокировки mutex- ›создают поток-› сигналы- ›unlocks, но к тому времени, когда этот поток пытается заблокировать мьютекс, main не разблокировал его, так что опять же, как он может ждать его, когда он сигнализировал? - person JamesTheProg; 15.06.2020
comment
Ключевым моментом здесь является то, что поток должен ждать, прежде чем основные блокировки и сигнализируют о мьютексе. Запустите поток и дождитесь выполнения условия в цикле (скажем, while(!condition) { pthread_cond_wait(...)}). Затем в главном блокировке мьютекса измените состояние и сигнал. То, как вы настраиваете свой тестовый код, вводит вас в заблуждение, - person Burak Serdar; 15.06.2020