首页 > 解决方案 > c中的父子共享缓冲区溢出

问题描述

我正在尝试使用 mmap 创建共享缓冲区。该代码应该使用计算每一行的进程输出一个 mandelbrot 集。每个计算行的进程都会将其存储在共享缓冲区中,然后我们必须将缓冲区输出到标准输出。但是我注意到缓冲区在线程函数内被正确填充,但是当我尝试在 main() 中打印缓冲区时,一半溢出了。

#include <stdio.h>
#include <unistd.h>
#include <assert.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <semaphore.h>
/*TODO header file for m(un)map*/

#include "mandel-lib.h"

#define MANDEL_MAX_ITERATION 100000

/***************************
 * Compile-time parameters *
 ***************************/
int N;
volatile int *shared_buff;
/*
 * Output at the terminal is is x_chars wide by y_chars long
*/
int y_chars = 50;
int x_chars = 90;

/*
 * The part of the complex plane to be drawn:
 * upper left corner is (xmin, ymax), lower right corner is (xmax, ymin)
*/
double xmin = -1.8, xmax = 1.0;
double ymin = -1.0, ymax = 1.0;
    
/*
 * Every character in the final output is
 * xstep x ystep units wide on the complex plane.
 */
double xstep;
double ystep;

int safe_atoi(char *s){
    long l;
    char *endp;
    l = strtol(s,&endp,10);
    if(s != endp && *endp == '\0'){
        return l;
    }
    else{
        return -1;
    }
}



/*
 * This function computes a line of output
 * as an array of x_char color values.
 */
void compute_mandel_line(int line, int color_val[])
{
    /*
     * x and y traverse the complex plane.
     */
    double x, y;

    int n;
    int val;
    /* Find out the y value corresponding to this line */
    y = ymax - ystep * line;

    /* and iterate for all points on this line */
    for (x = xmin, n = 0; n < x_chars; x+= xstep, n++) {

        /* Compute the point's color value */
        val = mandel_iterations_at_point(x, y, MANDEL_MAX_ITERATION);
        if (val > 255)
            val = 255;

        /* And store it in the color_val[] array */
        val = xterm_color(val);
        color_val[n] = val;
    }

}

/*
 * This function outputs an array of x_char color values
 * to a 256-color xterm.
 */
void output_mandel_line(int line,volatile int buff[], int color_val[])
{
    int i;
    
    char point ='@';
    char newline='\n';

    for (i = 0; i < x_chars; i++) {
        /* Set the current color, then output the point */
        buff[i+x_chars*line] = color_val[i];
        /* code for testing buffer line 40:
        if(line==40) printf("buff:%d color: %d",buff[i+x_chars*line],color_val[i]); */  
    }
    
    //printf("Line %d write to buffer\n",line);
}

void compute_and_output_mandel_line(volatile int buff[], int line)
{
    /*
     * A temporary array, used to hold color values for the line being drawn
     */
    int color_val[x_chars];

    compute_mandel_line(line, color_val);
    output_mandel_line(line,buff, color_val);
}




void child_func(int arg, volatile int buff[]){

    int color_val[x_chars];
    volatile long int i;
    size_t proc_num = (size_t)arg;
    for(i = proc_num; i < y_chars; i += N){
        
        compute_mandel_line(i,color_val);
        output_mandel_line(i,buff,color_val);

        /* code for testing if line 40 of the buffer is filled:
            if(i==40){
            int j;
            for(j=0;j<x_chars;j++){
                printf("buffer: %d", buff[j+x_chars*40]);
            }
        }
       */

    }
    printf("process %d exiting\n",proc_num);
}
int main(int argc, char *argv[])
{
    int line;
    xstep = (xmax - xmin) / x_chars;
    ystep = (ymax - ymin) / y_chars;
    N = safe_atoi(argv[1]);
    if(N < 1){
        perror("invalid num of threads");
        exit(1);
    }   
    size_t i;
    shared_buff = mmap(NULL,y_chars*x_chars,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANON,-1,0); 

    pid_t *pids = malloc(N* sizeof(*pids));
    if(pids == NULL){
        perror("Failed to allocate memory");
        exit(1);

    }
    for(i = 0; i < N; i++){

        pids[i] = fork();
        printf("%d\n",pids[i]);
        if(pids[i] < 0){
            perror("err");
            exit(1);
        }
        if(pids[i] == 0){
            child_func(i,shared_buff);
            exit(0);
        }
    }
    
    
    /*int j;
    for(j=0;j<x_chars;j++) printf("buffer received: %d",shared_buff[j+x_chars*40]);
    */
    char point = '@';
    char newline = '\n';

    for (line = 0; line<y_chars; line++){
        for (i = 0; i<x_chars; i++){
            set_xterm_color(1, shared_buff[i+line*x_chars]);
        
        if (write(1, &point, 1) != 1) {
            perror("compute_and_output_mandel_line: write point");
            exit(1);
        }
        }   

    // Now that the line is done, output a newline character 
        if (write(1, &newline, 1) != 1) {
            perror("compute_and_output_mandel_line: write newline");
            exit(1);
        }

    }

    reset_xterm_color(1);
    exit(0);
    return 0;
}

标签: cprocessoperating-systemshared-memorymmap

解决方案


推荐阅读