2011-04-07 123 views
0

我有典型的生产者&消费问题麻烦,我有一个主线程将被运行的生产功能和消费功能的多个线程调用;从一个缓冲区中取出物品并使用安全的互斥锁将其置于另一个缓冲区中。我想我需要两个互斥锁来管理这两个缓冲区,但我正在运行在一个终极循环中。线程同步:C

CODE:

int add_rule_input(rule_t* rule, rule_node_t* list) { 
    int i, error; 
str_node_t* sptr; 
rule_node_t* rptr; 


if(error = pthread_mutex_lock(&mut_access)){ 
     return error; 
} 

error = pthread_cond_wait(&buffer_empty, &mut_access); 

//first check to see if dependencies are in the output queue  
for(sptr = rule->deps; sptr != NULL; sptr = sptr->next){ 
     dep_count++; 
pthread_mutex_lock(&mut_output); 
for(i = 0; i < ArraySize; i++){ 

    if(outputQ[i] != NULL){ 

if(strcmp(sptr->str, outputQ[i]) == 0){ 
    array_count++; 
       break; // go the next rule in the output q 
     }else{ 
      //means the first element in our array did not have the current 
       continue;  
      } 
     }else{ 
error = pthread_cond_wait(&buffer_empty, &mut_output); 
      break; 
} 
    } 
}  
pthread_mutex_unlock(&mut_output); 

inputQ[bufin] = rule->target;//the element wherever the current place is 
printf("buffer got %s buffin = %d\n\n", inputQ[bufin], bufin); 
bufin = (bufin + 1); 
totalitems++; 
pthread_cond_signal(&buffer_full); 

return pthread_mutex_unlock(&mut_access); 

} 

正在访问的其它输出缓冲区

static void *consumer(void *arg){ 

rule_node_t* lptr = (rule_node_t*)arg; 
str_node_t* dptr; 
int error, i, j; 
int test1 = 0; 
//grab lock to read the input queue 
    if(error = pthread_mutex_lock(&mut_access)) 
    return error; 


if(error){ 

     pthread_mutex_unlock(&mut_access); 
     return error; 
    } 


// loop through all our rules 
    while(lptr != NULL){ 

// loop through each rules dependencies to compare with item in the input queue 
    for(dptr = lptr->rule->deps; dptr != NULL; dptr = dptr->next){ 
    // now loop through our input q if we get the lock 
     for(j = 0; j > ArraySize; j++){ 

       if(inputQ[j] != NULL){ 

     if(strcmp(dptr->str, inputQ[j]) == 0){ 
      fake_exec(lptr->rule); // if we get here there is a rule that needs to be executed 
      pthread_mutex_lock(&mut_output); 
      //update the output queue and release the lock 

     if(outputQ[bufout] == NULL){ 
    outputQ[bufout]= lptr->rule->target; 
    bufout = (bufout + 1); 
    printf("bufout has %s\n", outputQ[bufout]); 

    } 
    pthread_mutex_unlock(&mut_output); 
}       
    } 
    } 
error = pthread_cond_wait(&buffer_full, &mut_access); 
} 
    lptr = lptr->next; 
} 
pthread_cond_signal(&buffer_empty); 
pthread_mutex_unlock(&mut_access); 


} 

问题我的消费函数: 1}我已经试过先抢锁我的第一个缓冲区(inputq)并添加项目,如果我达到了一个点,没有更多的项目,那么我想释放这个锁定,所以我的消费者可以从缓冲区中取出这些项目,并将它们放在outputq中,出于某种原因,它似乎是主线程不等待并释放锁定?

回答

0

我在这里看到几个问题。第一个是在生产者部分用于(sptr = rule-> deps; sptr!= NULL; sptr = sptr-> next)循环。在这个循环内部,您可以锁定mut_output互斥锁,因此可以多次锁定它(如果它是递归互斥锁),但是在循环结束时仅解锁一次。

另一个问题是与pthread_cond_wait(& buffer_empty,& mut_output);.让我们想象一下这个制片人的等待时间。当它被执行时互斥锁mut_access被生产者锁定,现在当消费者被执行时它试图获取mut_access,但它不能够,因为它已经被锁定,所以消费者等待,当新信号触发buffer_empty条件变量解锁生产者。 可能在此pthread_cond_wait中,您想要传递mut_access而不是mut_output。