views:

47

answers:

2

Hey all,

Quite a specific question, but I was wondering if anyone has had any problems getting the first signal to be caught in a consumer-producer relationship with multiple consumers (HTTP web server)

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);
      }
+1  A: 

I feel changing the order of incrementing 'numRequests' in producer will ensure the consumer will not miss the first signal.

Existing sequence: numRequests++; pthread_cond_signal(&condVars[nextWorker]);

Proposed sequence: pthread_cond_signal(&condVars[nextWorker]); numRequests++;

Rationale: When the consumer enters execution of the loop 'numRequests == 0' and then perform a wait on the conditional variable, the 'numRequests' can be non-zero and the signal is not yet signaled. The consumer will not enter the loop since 'numRequests' is non zero and miss the signal which will be signaled by producer after incrementing.

hackworks
+1  A: 

I don't believe the previous answer solves the problem, because both operations are being performed inside the critical section.

I would recommend using a counting semaphore instead of an integer for numRequests. The producer performs a sem_post() and the consumers perform a sem_wait(). The first consumer to return from the wait will decrement the semaphore and can then lock the mutex only when modifying shared variables, minimizing the code inside the critical section, and imposing a sense of order that is not provided by mutexing alone.

Adam