【问题标题】:Thread Synchronization using two buffers and two mutex locks: C使用两个缓冲区和两个互斥锁的线程同步:C
【发布时间】:2023-04-02 04:17:01
【问题描述】:

我遇到了典型的生产者和消费者问题,我有一个主线程将使用的生产者函数和一个多个线程调用的消费者函数;从一个缓冲区中取出项目并使用安全互斥锁将它们放置在另一个缓冲区中。我想我需要两个互斥锁来管理两个缓冲区,但我正在一个最终循环中运行。

代码:

    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)的锁并向其中添加项目,如果我达到没有更多项目的地步,那么我想释放这个锁,以便我的消费者可以从buffer 并将它们放在 outputq 中,由于某种原因,主线程似乎没有等待并释放锁?

【问题讨论】:

    标签: c multithreading synchronization deadlock mutex


    【解决方案1】:

    我在这里看到了一些问题。第一个是 for(sptr = rule->deps; sptr != NULL; sptr = sptr->next) 循环的生产者部分。在这个循环中,你锁定了 mut_output 互斥体,所以它可以被多次锁定(如果它是递归互斥体),但在循环结束时只能解锁一次。

    另一个问题是 pthread_cond_wait(&buffer_empty, &mut_output);。让我们想象一下制作人的等待是午餐。当它吃午饭时,mutex mut_access 被生产者锁定,现在当消费者被执行时,它试图获取 mut_access,但它不能,因为它已经被锁定,所以消费者也在等待和更新的到达部分,当它发出 buffer_empty 条件变量来解锁生产者时. 可能在这个 pthread_cond_wait 中,您想传递 mut_access 而不是 mut_output。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-07
      • 1970-01-01
      • 2014-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多