简体   繁体   中英

Thread Synchronization using two buffers and two mutex locks: C

I am having trouble with the typical Producer & Consumer problem , i have a producer function that the main thread will be operating with and a consumer function that multiple threads call; taking items from one buffer and placing them in another using a safe mutex lock. Im thinking i need two mutex locks to manage both buffers but i am running in an ultimate loop.

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);

}

My consumer function that is accessing the other output buffer

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);  


 }

QUESTIONS: 1} I have tried to first grab the lock for my first buffer(inputq) and add items to it, if i reach a point where there are no more items then i want to release this lock so my consumer can take these items from the buffer and place them in the outputq, for some reason it seems as the main thread does not wait and release the lock?

I see here few problems. First one is in producer part with for(sptr = rule->deps; sptr != NULL; sptr = sptr->next) loop. Inside this loop you lock mut_output mutex, so it can be locked multiple time (if it is recursive mutex), but is unlocked only once when loop ends.

Another problem is with pthread_cond_wait(&buffer_empty, &mut_output);. Lets imagine this wait in producer is lunched. When it is lunched mutex mut_access is locked by producer, and now when consumer is executed it try to acquire mut_access, but it cant because it it already locked so the consumer waits as well and newer reach part when it signal buffer_empty conditional variable to unlock producer. Probably in this pthread_cond_wait you wanted to pass mut_access instead of mut_output.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM