UNIX共享内存

时间:2012-11-08 14:36:02

标签: c unix shared-memory

  

可能重复:
  Unix Programming Shared Memory strange results

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

这是共享内存代码:

#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;
}

现在问题是第二个版本运行良好,矩阵通过我在calculate函数中定义的规则演变,但是在第一个代码中它始终是相同的...甚至根本不包含...两个版本正在努力编写...... 如果你可以帮我解决这个问题,我将非常感激。

0 个答案:

没有答案