使用两个缓冲区和两个互斥锁的线程同步:C

发布于 2024-10-31 04:50:24 字数 2931 浏览 0 评论 0原文

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

代码:

    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中,由于某种原因,主线程似乎没有等待并释放锁?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

独自←快乐 2024-11-07 04:50:24

我在这里看到几个问题。第一个是在生产者部分,使用 for(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。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文