相当具体的问题,但我想知道是否有任何人在与多个消费者(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);
}
答案 0 :(得分:1)
我觉得改变生成器中'numRequests'递增的顺序将确保消费者不会错过第一个信号。
现有顺序: numRequests ++; 调用pthread_cond_signal(安培;条件变量[nextWorker]);
建议的顺序: 调用pthread_cond_signal(安培;条件变量[nextWorker]); numRequests ++;
理由: 当消费者进入循环'numRequests == 0'的执行然后对条件变量执行等待时,'numRequests'可以是非零并且信号尚未发出信号。消费者不会进入循环,因为'numRequests'不为零并且错过了增量后生产者将发出信号的信号。
答案 1 :(得分:1)
我不相信之前的答案可以解决问题,因为这两项操作都是在关键部分内进行的。
我建议使用计数信号量而不是numRequests
的整数。生产者执行sem_post()
,消费者执行sem_wait()
。从等待返回的第一个消费者将减少信号量,然后只有在修改共享变量时才能锁定互斥锁,最小化关键部分内的代码,并强加一种单独的静音不提供的顺序感。