2013-03-27 90 views
0

我正在使用共享内存的信号量用于多生产者和多客户端之间的通信。我的系统中有两种主要的信号量,它们是“存储信号量”和“处理信号量”。如何在一组信号上有效等待?

系统运行如下:生产者连续地将数据放入共享内存中,然后增加存储的信号量的值,同时消费者在循环中,等待这样存储的信号量。消费者在收到生产者的数据后,将处理这些数据,然后提高处理过的信号量的价值。

for(int i =0;i<nloop;i++){ 
    usleep(100); 
    strcpy(shared_mem[i], "data for processing"); 
    sem_post(&shared_mem[i].stored_semaphored); 
    if(sem_timedwait(&msg_ptr->processed_semaphore,&ts)==-1){ //waiting for result 
     if(errno == ETIMEDOUT){ 
     } 
     break; 
    }else{ 
     //success 
    } 

} 

消费者代码:

for (int j = 0; j < MAX_MESSAGE; j++) { 
if (sem_trywait(&(shm_ptr->messages[j].stored_semaphore)) == -1) { 
    if (errno == EAGAIN) { 
    } else { 
      //success ==> process data 
      //post result back on the shared memory, and increase       
      //the processed semahore 
     strcpy(shared_mem[j].output, "Processed data"); 
     sem_post(&(shared_mem[j].processed_semaphore)); 
    } 
} 
}//for loop over MAX_MESSAGE 

我的问题是,在消费代码回路是生产商将通过“加工信号”等待

生产者代码得到他们的结果浪费几乎100%的CPU,因为在没有来自制造商的数据的情况下,这为循环连续运行。

我的问题是,有任何其他方式等待一组信号量(可能类似于通过SELECT,POLL或EPOLL等待机制),这不会浪费CPU时间。

希望看到你的答案。非常感谢!

+0

共享资源池应该由一个信号量控制,而不是由一个集合控制。 – 2013-03-27 04:28:36

回答

1

据我所知,没有办法等待一组信号量。这意味着所有的访问都需要通过单个信号量来完成。你在循环一组信号量,所以它们可以成为一个对象。该消费者需要知道何时信号已经发出信号,因此在新的信号量上使用额外的sem_post来表示该信号量已经改变。

你制作的代码变得像这样:

.... 
sem_post(&shared_mem[i].stored_semaphored); 
sem_post(&list_changed_semaphore); /* Wake the consumer. */ 
.... 

和消费者:

/* Block until a consumer has indicated that it has changed the semaphore list */ 
if (!sem_wait(&list_changed_semaphore)) { 
    /* At least one producer has signalled a change. */ 
    for (int j = 0; j < MAX_MESSAGE; j++) { 
     if (sem_trywait(&(shm_ptr->messages[j].stored_semaphore)) == -1) { 
     } 
    } 
} 

而不是使用一个信号量list_changed_semaphore你可以使用一个pthread_cond_t条件变量信号中的东西你一套信号量已经改变。 list_changed_semaphore不需要像这里所示的示例那样是一个计数器,它只需要一个位来指示生产者已经修改了列表。

+0

菲利普斯:谢谢你的深思熟虑的答案!它解决了我的问题。 – khanhhh89 2013-03-27 07:34:12