c - 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;
}
解决方案
推荐阅读
- r - 如何pivot_longer 一组多列?以及如何从那种长格式回到原来的宽格式?
- sql - 为成千上万行更新多列的更快方法
- python - Python - 获取所有形式的单词
- ios - Objective-C 中的类可用性
- c - 在linux中用c获取文件的信息
- operating-system - 如何为 FreeBSD 内核创建系统调用
- node.js - 无法连接到 Mongo Atlas getaddrinfo ENOTFOUND [集群名称]
- javascript - 样式化的组件在点击时播放动画
- arrays - ifs 的数组参数大小不同
- arrays - 如何从 UITableView 访问保存的数组结构中的字符串