Сигнал первого потока не пойман, все остальные пойманы - PullRequest
2 голосов
/ 01 декабря 2009

Довольно конкретный вопрос, но мне было интересно, если у кого-то возникли проблемы с получением первого сигнала, который будет обнаружен в отношениях между потребителем и производителем с несколькими потребителями (веб-сервер HTTP)

for(i = 0; i < num_threads; i++) {
    pthread_cond_init(&condVars[i], NULL);
    if(strcmp(policy,"FIFO") == 0)
        pthread_create(&threadArr[i], NULL, workerFIFO, &condVars[i]);
    else
        pthread_create(&threadArr[i], NULL, workerSFF, &condVars[i]);

}


listenfd = Open_listenfd(port);
    // Producer
while (1) {
    clientlen = sizeof(clientaddr);
    connfd = Accept(listenfd, (SA *)&clientaddr, (socklen_t *) &clientlen);

    pthread_mutex_lock(&mutex);

    while(numRequests == num_buffers)
        pthread_cond_wait(&empty, &mutex);

    if(strcmp(policy,"FIFO") == 0)
        putFIFO(connfd);
    else
        putSFF(connfd);


    numRequests++;
    pthread_cond_signal(&condVars[nextWorker]);

    nextWorker = (nextWorker + 1) % num_threads;
    pthread_mutex_unlock(&mutex);
    printf("%s\n", "Look not dead!!!");

}

    // Consumer
    while(1){
    pthread_mutex_lock(&mutex);
    while(numRequests == 0) {
        printf("%u\n", condVar);
        pthread_cond_wait(condVar, &mutex);
        printf("%s", "caught it");
    }

    printf("%s, %u\n", "Its Workingzz! ZOMGZ!!!", condVar);


    int connfd = buffer[nextOutFIFO];
    nextOutFIFO = (nextOutFIFO + 1) % num_buffers;
    numRequests--;
    pthread_cond_signal(&empty);
    pthread_mutex_unlock(&mutex);
    requestHandle(connfd);

    Close(connfd);
      }

Ответы [ 2 ]

1 голос
/ 02 декабря 2009

Я не верю, что предыдущий ответ решает проблему, потому что обе операции выполняются внутри критической секции.

Я бы рекомендовал использовать счетный семафор вместо целого числа для numRequests. Производитель выполняет sem_post(), а потребители выполняют sem_wait(). Первый потребитель, вернувшийся из ожидания, уменьшит семафор и сможет заблокировать мьютекс только при изменении общих переменных, минимизации кода внутри критической секции и наложении чувства порядка, который не обеспечивается только мьютексом.

1 голос
/ 01 декабря 2009

Я чувствую, что изменение порядка увеличения 'numRequests' в производителе гарантирует, что потребитель не пропустит первый сигнал.

Существующая последовательность: numRequests ++; pthread_cond_signal (& condVars [nextWorker]);

Предлагаемая последовательность: pthread_cond_signal (& condVars [nextWorker]); numRequests ++;

Обоснование: Когда потребитель входит в выполнение цикла 'numRequests == 0' и затем выполняет ожидание условной переменной, 'numRequests' может быть ненулевым, и сигнал еще не передан. Потребитель не будет входить в цикл, поскольку numRequests не равен нулю и пропустит сигнал, который будет сообщен производителем после увеличения.

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