首页 > 解决方案 > 只有第一个缓冲区在用 C++ 实现的双缓冲区中工作

问题描述

我实现了一个双缓冲程序,在网上读取需要使用code和c++处理的缓冲区的txt文件,然后将处理结果输出为output.txt格式,但是不起作用。

这是我想要做的:

producer routine
buf1 full_flag : 0 , record_count : 1
buf2 full_flag : 0 , record_count : 0
producer routine
buf1 full_flag : 1 , record_count : 2
buf2 full_flag : 0 , record_count : 0
Consumer routine 
buf1 full_flag : 1 , record_count : 3
buf2 full_flag : 0 , record_count : 0
...
Consumer routine 
buf1 full_flag : 1 , record_count : 10
buf2 full_flag : 0 , record_count : 0
producer routine
buf1 full_flag : 1 , record_count : 1
buf2 full_flag : 1 , record_count : 1
Consumer routine 
buf1 full_flag : 1 , record_count : 1
buf2 full_flag : 1 , record_count : 2

但它实际上是这样工作的:

producer routine
buf1 full_flag : 0 , record_count : 1
buf2 full_flag : 0 , record_count : 0
producer routine
buf1 full_flag : 1 , record_count : 2
buf2 full_flag : 0 , record_count : 0
...
Consumer routine 
buf1 full_flag : 1 , record_count : 10
buf2 full_flag : 0 , record_count : 0
producer routine
buf1 full_flag : 1 , record_count : 1
buf2 full_flag : 0 , record_count : 0
Consumer routine 
buf1 full_flag : 1 , record_count : 2
buf2 full_flag : 0 , record_count : 0

不管我怎么看代码,我都不知道该怎么办。第一个缓冲区运行良好,但似乎指针在操作后没有越过第二个缓冲区。

也许结构或指针有问题。但我不知道如何处理这个问题。

如果您能帮助我,我将不胜感激。

这是代码:

#include <stdio.h>
struct buf{
    int buf_n;
    int full_flag;
    int record_counter;
    struct buf* next;
};
int main(){
    struct buf buf1, buf2;
    struct buf *to_fill,*to_empty;
    char str[9];
    int state;
    int i=0;
    int j=0;
    char* Pstate;
    int count=0;
    int n=sizeof(str);
    buf1.buf_n = 1;
    buf2.buf_n = 2;
    buf1.full_flag = 0;
    buf2.full_flag = 0;
    buf1.record_counter = 0;
    buf2.record_counter = 0;
    buf1.next = &buf2;
    buf2.next = &buf1;
    to_fill = &buf1;
    to_empty = &buf1;
    FILE* file=fopen("input.txt","rt");
    FILE* file2=fopen("output.txt","wt");
while(1){
wait: 
  if((*to_fill).full_flag == 1) goto Loop;
   Pstate = fgets(str,sizeof(str),file);
   if(Pstate==NULL)
    break;
   fputs(str, stdout);
  if((*to_fill).record_counter > n){
   (*to_fill).full_flag = 0;
   (*to_fill) = *(*to_fill).next;
  }
  (*to_fill).record_counter=1;
  (*to_fill).full_flag=1;
  (*to_fill) = *(*to_fill).next;
  fprintf(file2,"producer routine\n");
  fprintf(file2,"buf1 full_flag : %d , record_count : %d\n", buf1.full_flag, buf1.record_counter);
  fprintf(file2,"buf2 full_flag : %d , record_count : %d\n", buf2.full_flag, buf2.record_counter);
  i++;
  goto Loop;
Loop: 
  if((*to_empty).full_flag == 0) goto wait;
  (*to_empty).record_counter = (*to_empty).record_counter+1;
  fprintf(file2,"Consumer routine \n");
  fprintf(file2,"buf1 full_flag : %d , record_count : %d\n", buf1.full_flag, buf1.record_counter);
  fprintf(file2,"buf2 full_flag : %d , record_count : %d\n", buf2.full_flag, buf2.record_counter);
  if((*to_empty).record_counter > n){
   (*to_empty).full_flag = 0;
   (*to_empty) = *(*to_empty).next;
  }
  count++;
  if(count>1000){
   break;
  goto wait;
  }
 }
 state=fclose(file);
 state=fclose(file2);
 return 0;
}

此外,代码必须有一个 input.txt 文件,该文件与存储源文件的路径相同。

input.txt 文件的内容:

1234567890

标签: c++

解决方案


任何人都不容易分辨出哪里出了问题——这些 goto 是非常 1965 年的——但你正在分配*to_fill*to_empty期望分配到的位置to_fillto_empty
(该分配使您的两个缓冲区相同。特别是,to_fill->next并且to_empty->next是相同的。)

在 agoto 之后还有一个break,它没有效果。

稍微现代化您的代码并修复该分配使流程更清晰(为清楚起见删除了输出):

struct buf{
    int buf_n;
    bool is_full;
    int record_counter;
    buf* next;
};

int main(){
    buf buf1 = {1, false, 0};
    buf buf2 = {2, false, 0};
    buf1.next = &buf2;
    buf2.next = &buf1;

    int i = 0;
    char* Pstate = nullptr;
    int count = 0;
    char str[9];
    int n = sizeof(str);

    buf* to_fill = &buf1;
    buf* to_empty = &buf1;
    FILE* file = fopen("input.txt","rt");
    FILE* file2 = fopen("output.txt","wt");

    while(1){
        if(!to_fill->is_full){
            Pstate = fgets(str,sizeof(str),file);
            if(Pstate == NULL)
                break;
            fputs(str, stdout);
            if(to_fill->record_counter > n){
                to_fill->is_full = false;
                to_fill = to_fill->next;
            }
            to_fill->record_counter = 1;
            to_fill->is_full = true;
            to_fill = to_fill->next;
            i++;
        }
        if(to_empty->is_full) {
            to_empty->record_counter += 1;
            if(to_empty->record_counter > n){
                to_empty->is_full = 0;
                to_empty = to_empty->next;
            }
            count++;
            if(count > 1000){
                break;
            }
        }
    }
    fclose(file);
    fclose(file2);
    return 0;
}

现在,看起来还剩下很多错误 - 缓冲区切换看起来很不确定(例如,您可以切换to_fill两次,将其恢复到开始的位置)。
修复那些作为练习留下的错误。


推荐阅读