0

可能重复:
Unix Programming Shared Memory 奇怪的结果

我已经做了两个星期并学习如何使用共享内存,并且在一个较小的练习中我可以使它工作但现在我在以下代码中遇到了与我制作的其他顺序代码相关的问题......输出只是是相同的,并且不像顺序版本那样进行计算......并且代码是相同的......

这是共享内存代码:

#define MAX_SIZE 20

#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h> 
#include <sys/shm.h>
#include <stdio.h>
#include <sys/fcntl.h>
#include <semaphore.h>
#include <sys/wait.h>

#define MAXCHILDS 2
#define MAX_SIZE 20
#define MAX_WRITES 100
#define ALIVE 1
#define DEAD 0


typedef struct{
    int m[MAX_SIZE][MAX_SIZE];
    int h[MAX_SIZE][MAX_SIZE];
}matrix;

pid_t child[MAXCHILDS];
matrix*sh_mem;
int shmid;
int gen = 5; 


void calculate() { // filhos checks if the cells around obey these rules are changed to 1 or 0 
        int tableB[MAX_SIZE][MAX_SIZE];
        int neighbor, height, width;


        for (height = 0; height < MAX_SIZE; height++) {
                for (width = 0; width < MAX_SIZE; width++) {
                        neighbor = getNeighborCount(sh_mem->m, height, width);
                        if (neighbor==3) {
                                tableB[height][width] = ALIVE;
                        } else if (neighbor == 2 && sh_mem->m[height][width] == ALIVE) {
                                tableB[height][width] = ALIVE;
                        } else {
                                tableB[height][width] = DEAD;
                        }
                }
        }

        for (height = MAX_SIZE; height < MAX_SIZE; height++) {
                for (width = MAX_SIZE; width < MAX_SIZE; width++) {
                        sh_mem->m[height][width] = tableB[height][width];
                }
        }
}
int getNeighborValue(int table[MAX_SIZE][MAX_SIZE], int row, int col) { // gets the neighborvalue
        if (table[row][col] == ALIVE) 
        { 
                return 1;
        } else {
                return 0;
        }
}
int getNeighborCount(int table[MAX_SIZE][MAX_SIZE], int row, int col) { // gets the cells around 
        int neighbor = 0;

        neighbor += getNeighborValue(table, row - 1, col - 1);  //top left
        neighbor += getNeighborValue(table, row - 1, col);  //top
        neighbor += getNeighborValue(table, row - 1, col + 1);  //top right
        neighbor += getNeighborValue(table, row, col - 1);  //left
        neighbor += getNeighborValue(table, row, col + 1);  //right
        neighbor += getNeighborValue(table, row + 1, col - 1);  //below left
        neighbor += getNeighborValue(table, row + 1, col);   // below
        neighbor += getNeighborValue(table, row + 1, col + 1);  //below right

        return neighbor;
}
void printTable(int table[MAX_SIZE][MAX_SIZE]) {
        int height, width;

        for (height = 0; height < MAX_SIZE-1; height++) {
                for (width = 0; width < MAX_SIZE-1; width++) {
                        if (table[height][width] == 1) {
                                printf(" X ");
                        } else {
                                printf(" . ");
                        }
                }
                printf("\n");
        }
        printf("\n");
}
void init(){

    /*initialize shared memory */
    shmid = shmget(IPC_PRIVATE,sizeof(matrix),IPC_CREAT|0777);
    /*map shared memory*/
    sh_mem = (matrix*)shmat(shmid,NULL,0);
    if(sh_mem == (matrix*)(-1)){
        perror("shmat");
    }
}
void terminate() {
  shmctl(shmid, IPC_RMID, NULL);
}

void initarray() {
  int i,j; 
  for (i=0; i<MAX_SIZE-1; i++){
    for (j=0; j<MAX_SIZE-1; j++){
        if(drand48()>0.5){
            sh_mem->m[i][j] = 1;
        }
        else{
            sh_mem->m[i][j] = 0;
        }
    }
  }
} 


int matchArray(){ // funcao para o parent // checks the matrix for differences with previous matrix
        int count = 0;
        int height,width,flag=0;
        for(height = 0; height<MAX_SIZE; height++){
                for(width = 0; width<MAX_SIZE; width++){
                        if(sh_mem->m[height][width] != sh_mem->h[height][width]){
                                count++;
                        }
                }
        }
        if(count>0){
                flag = 1;
        }
        return flag;
}

int main(int argc, char **argv)
{   
    int i,k;
    int generation = 0;
    int height,width;
    int flag = 0;
    init();
    initarray(sh_mem->m);
    printTable(sh_mem->m);
    printf("Test data as Generation 0\n");
    printf("-----------\n");


      for(i=0; i<gen; i++)
    {
                for (height = 0; height < MAX_SIZE; height++) {
                    for (width = 0; width < MAX_SIZE; width++) {
                            sh_mem->h[height][width] = sh_mem->m[height][width];
                    }
                }
                calculate();
                flag = matchArray();
                printf("The flag value is:%d\n",flag);
                if(flag == 0){
                    break;
                }
                        printTable(sh_mem->m);
                printf("\n======================================\n");
                printTable(sh_mem->h);
                        printf("Generation %d\n", ++generation);
        }

    return 0;
}

连续版本是:

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <math.h>
#include <sys/time.h>

#define ALIVE 1
#define DEAD 0

int **array = NULL;
int **history = NULL;
int HEIGHT;
int WIDTH;

double gettime(void) {
  struct timeval tval;

  gettimeofday(&tval, NULL);

  return( (double)tval.tv_sec + (double)tval.tv_usec/1000000.0 );
}

//Its showing answer with small size matrices, but not with bigger ones

int **allocarray(int P, int Q) {
  int i;
  int *p, **a;
  p = (int *)malloc(P*Q*sizeof(int));
  a = (int **)malloc(P*sizeof(int*));
  if (p == NULL || a == NULL) 
    printf("Error allocating memory\n");
  /* for row major storage */
  for (i = 0; i < P; i++)
    a[i] = &p[i*Q];
  return a;
}
void initarray() {
  int i,j; 
  for (i=1; i<HEIGHT-1; i++){
    for (j=1; j<WIDTH-1; j++){
        if(drand48()>0.5){
            array[i][j] = 1;
        }
        else{
            array[i][j] = 0;
        }
    }
  }
} 
void printTable(int **table) {
        int height, width;

        for (height = 1; height < HEIGHT-1; height++) {
                for (width = 1; width < WIDTH-1; width++) {
                        if (table[height][width] == ALIVE) {
                                printf(" X ");
                        } else {
                                printf(" 0 ");
                        }
                }
                printf("\n");
        }
        printf("\n");
}

//to clear up everything

void clearTable() {
        int height, width;
        for (height = 0; height < HEIGHT; height++) {
                for (width = 0; width < WIDTH; width++) {
                        array[height][width] = DEAD;
                }
        }
}

int getNeighborValue(int **table, int row, int col) {
        if (table[row][col] == ALIVE) 
        { 
                return 1;
        } else {
                return 0;
        }
}


int getNeighborCount(int **table, int row, int col) {
        int neighbor = 0;

        neighbor += getNeighborValue(table, row - 1, col - 1);  //top left
        neighbor += getNeighborValue(table, row - 1, col);  //top
        neighbor += getNeighborValue(table, row - 1, col + 1);  //top right
        neighbor += getNeighborValue(table, row, col - 1);  //left
        neighbor += getNeighborValue(table, row, col + 1);  //right
        neighbor += getNeighborValue(table, row + 1, col - 1);  //below left
        neighbor += getNeighborValue(table, row + 1, col);   // below
        neighbor += getNeighborValue(table, row + 1, col + 1);  //below right

        return neighbor;
}

void calculate() {
        int **tableB = NULL;
        int neighbor, height, width;
        tableB = allocarray(HEIGHT, WIDTH);

        for (height = 1; height < (HEIGHT-1); height++) {
                for (width = 1; width < (WIDTH-1); width++) {
                        neighbor = getNeighborCount(array, height, width);
                        if (neighbor==3) {
                                tableB[height][width] = ALIVE;
                        } else if (neighbor == 2 && array[height][width] == ALIVE) {
                                tableB[height][width] = ALIVE;
                        } else {
                                tableB[height][width] = DEAD;
                        }
                }
        }

        for (height = 1; height < (HEIGHT-1); height++) {
                for (width = 1; width < (WIDTH-1); width++) {
                        array[height][width] = tableB[height][width];
                }
        }
}

int matchArray(){
        int count = 0;
        int height,width,flag=0;
        for(height = 0; height<HEIGHT; height++){
                for(width = 0; width<WIDTH; width++){
                        if(array[height][width] != history[height][width]){
                                count++;
                        }
                }
        }
        if(count>0){
                flag = 1;
        }
        return flag;
}


int main(int argc, char *argv[]) {
        int generation = 0;
        int i;
        double starttime, endtime, time;
        int height,width;
        int flag = 0;
    if (argc!=3)
        printf("You need to enter the size of the matrix and the number of generations in the comment line arguement\n");
    else
    {
        printf("The matrix size given is:%s\n",argv[1]);
        HEIGHT = atoi(argv[1])+2;
        WIDTH = HEIGHT;
        array = allocarray(HEIGHT, WIDTH);
        history = allocarray(HEIGHT, WIDTH);
        clearTable();
        // askUser(table);
        //loadTestData(array);
        initarray();
        printTable(array);
        printf("Test data as Generation 0\n");
        printf("-----------\n");
        starttime= gettime();
        printf("Starttime= %f", starttime);
        for(i=0; i<(atoi(argv[2])); i++)
    {
                for (height = 0; height < HEIGHT; height++) {
                    for (width = 0; width < WIDTH; width++) {
                            history[height][width] = array[height][width];
                    }
                }
                calculate();
                flag = matchArray();
                printf("The flag value is:%d\n",flag);
                if(flag == 0){
                    break;
                }
                        printTable(array);
                printf("\n======================================\n");
                printTable(history);
                        printf("Generation %d\n", ++generation);
        }
    endtime= gettime();
    printf("Endtime= %f", endtime);

    time= (endtime-starttime);
    printf("Time taken= %1f\n", time); 
    } 
        return 0;
}

现在的问题是第二个版本运行良好,矩阵通过我在计算函数中定义的规则演变,但在第一个代码中它总是相同的......甚至根本不涉及......这两个版本正在工作并且准备编译...如果你能帮我解决这个问题,我将不胜感激。

4

0 回答 0