-3

pthreads を使用してエボラ シミュレーションを実行しようとしています。セマフォ部分まではすべてうまくいきました。コードのコンパイル中に次のエラーが発生します。

  *** Error in `./ebola_serial': double free or corruption (out): 0x00007f49700008c0 ***
  *** Error in `======= Backtrace: =========
  /lib64/libc.so.6(+0x7238e)[0x7f49868f038e]
  ./ebola_serial/lib64/libc.so.6(+0x7a0c8)[0x7f49868f80c8]
  ': /lib64/libc.so.6(cfree+0x48)[0x7f49868fb798]
  double free or corruption (out)/lib64/libc.so.6(fclose+0x113)[0x7f49868e6473]
  ./ebola_serial[0x401717]
  /lib64/libpthread.so.0(+0x75bd)[0x7f4986c395bd]
  : 0x/lib64/libc.so.6(clone+0x6d)[0x7f498697562d]
  ======= Memory map: ========
  00007f49700008c000400000-00402000 r-xp 00000000 08:01 802698                             /home/name/Desktop/try ca/ebola_serial
  00601000-00602000 r--p 00001000 08:01 802698                             /home/name/Desktop/try ca/ebola_serial
  00602000-00603000 rw-p 00002000 08:01 802698                             /home/name/Desktop/try ca/ebola_serial
  00603000-009d3000 rw-p 00000000 00:00 0 
  01b96000-01bb7000 rw-p 00000000 00:00 0                                  [heap]
  7f4970000000-7f4970021000 rw-p 00000000 00:00 0 
  7f4970021000-7f4974000000 ---p 00000000 00:00 0 
  7f4978000000-7f4978021000 rw-p 00000000 00:00 0 
  7f4978021000-7f497c000000 ---p 00000000 00:00 0 
  7f497c000000-7f497c021000 rw-p 00000000 00:00 0 
  7f497c021000-7f4980000000 ---p 00000000 00:00 0 
  7f4980000000-7f4980021000 rw-p 00000000 00:00 0 
  7f4980021000-7f4984000000 ---p 00000000 00:00 0 
  7f4984663000-7f4984679000 r-xp 00000000 08:01 131531                     /usr/lib64/libgcc_s-4.9.2.so.1
  7f4984679000-7f4984878000 ---p 00016000 08:01 131531                     /usr/lib64/libgcc_s-4.9.2.so.1
  7f4984878000-7f4984879000 r--p 00015000 08:01 131531                     /usr/lib64/libgcc_s-4.9.2.so.1
  7f4984879000-7f498487a000 rw-p 00016000 08:01 131531                     /usr/lib64/libgcc_s-4.9.2.so.1
  7f498487a000-7f498487b000 ---p 00000000 00:00 0 
  7f498487b000-7f498507b000 rw-p 00000000 00:00 0                          [stack:7376]
  7f498507b000-7f498507c000 ---p 00000000 00:00 0 
  7f498507c000-7f498587c000 rw-p 00000000 00:00 0 
  7f498587c000-7f498587d000 ---p 00000000 00:00 0 
  7f498587d000-7f498607d000 rw-p 00000000 00:00 0                          [stack:7374]
  7f498607d000-7f498607e000 ---p 00000000 00:00 0 
  7f498607e000-7f498687e000 rw-p 00000000 00:00 0                          [stack:7373]
  7f498687e000-7f4986a28000 r-xp 00000000 08:01 130947                     /usr/lib64/libc-2.20.so
  7f4986a28000-7f4986c28000 ---p 001aa000 08:01 130947                     /usr/lib64/libc-2.20.so
  7f4986c28000-7f4986c2c000 r--p 001aa000 08:01 130947                     /usr/lib64/libc-2.20.so
  7f4986c2c000-7f4986c2e000 rw-p 001ae000 08:01 130947                     /usr/lib64/libc-2.20.so
  7f4986c2e000-7f4986c32000 rw-p 00000000 00:00 0 
  7f4986c32000-7f4986c49000 r-xp 00000000 08:01 130973                     /usr/lib64/libpthread-2.20.so
  7f4986c49000-7f4986e48000 ---p 00017000 08:01 130973                     /usr/lib64/libpthread-2.20.so
  7f4986e48000-7f4986e49000 r--p 00016000 08:01 130973                     /usr/lib64/libpthread-2.20.so
  7f4986e49000-7f4986e4a000 rw-p 00017000 08:01 130973                     /usr/lib64/libpthread-2.20.so
  7f4986e4a000-7f4986e4e000 rw-p 00000000 00:00 0 
  7f4986e4e000-7f4986f53000 r-xp 00000000 08:01 130955                     /usr/lib64/libm-2.20.so
  7f4986f53000-7f4987152000 ---p 00105000 08:01 130955                     /usr/lib64/libm-2.20.so
  7f4987152000-7f4987153000 r--p 00104000 08:01 130955                     /usr/lib64/libm-2.20.so
  7f4987153000-7f4987154000 rw-p 00105000 08:01 130955                     /usr/lib64/libm-2.20.so
  7f4987154000-7f4987174000 r-xp 00000000 08:01 130940                     /usr/lib64/ld-2.20.so
  7f4987353000-7f4987356000 rw-p 00000000 00:00 0 
  7f498736d000-7f4987373000 rw-p 00000000 00:00 0 
  7f4987373000-7f4987374000 r--p 0001f000 08:01 130940                     /usr/lib64/ld-2.20.so
  7f4987374000-7f4987376000 rw-p 00020000 08:01 130940                     /usr/lib64/ld-2.20.so
  7ffce31e3000-7ffce3205000 rw-p 00000000 00:00 0                          [stack]
  7ffce320d000-7ffce320f000 r--p 00000000 00:00 0                          [vvar]
  7ffce320f000-7ffce3211000 r-xp 00000000 00:00 0                          [vdso]
  ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
  Aborted

これは私のコードです:

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include "timer.h"
#define NUMROW 1000
#define NUMCOL 1000
#define NUMCOMP 1000000
#define GEN 400
#define THREAD_COUNT 4

FILE *fp;
char buffer[32];

int map[1000][1000];
int neighbours[8];
int nextGen;
double chance;

int tInfection = 0;
int tHealthy = 0;
int tDead = 0;
int tRecovered = 0;

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

sem_t semaphores[THREAD_COUNT];

int barrCount1,
barrCount2, totalDead, totalHealthy, totalInfection, totalRecovered, p;
pthread_mutex_t barrier_mutex;

void* mythread_func(void* rank)
{
  long my_rank = (long) rank;
  long i, j;
  long my_row = NUMROW / THREAD_COUNT;
  long my_col = my_row;
  long my_first_i = my_row * my_rank;
  long my_last_i = my_first_i + my_row - 1;

  for (i = my_first_i; i < my_last_i; i++)
  {
    for (j = my_first_i; j < my_last_i; j++)
    {
      map[i][j] = 0;
    }
  }

  int inf;
  //infecting 5 random people
  for (inf = 0; inf < 1; inf++)
  {
    double rand1 = floor(rand() % ((my_last_i + 1 - my_first_i) + my_first_i));
    double rand2 = floor(rand() % ((my_last_i + 1 - my_first_i) + my_first_i));

    int randFin1 = (int) rand1;
    int randFin2 = (int) rand2;

    map[randFin1][randFin2] = 1;

  }

  int k = 0;
  long dest = (my_rank + 1) % THREAD_COUNT;

  long genCount;

  //loops of generation
  for (genCount = 0; genCount < GEN; genCount++)
  {

    //mutex barrier---------------------------
    pthread_mutex_lock(&barrier_mutex);
    barrCount1++;
    pthread_mutex_unlock(&barrier_mutex);
    while (barrCount1 < THREAD_COUNT)
      ;
    //----------------------------------------

    //looping through columns and rows
    for (i = my_first_i; i < my_last_i; i++)
    {
      for (j = my_first_i; j < my_last_i; j++)
      {

        nextGen = 1;

        //left neigbour
        neighbours[0] = map[(i + NUMROW - 1) % NUMROW][j];

        //right neighbour
        neighbours[1] = map[(i + NUMROW + 1) % NUMROW][j];

        //top neighbour
        neighbours[2] = map[i][(j + NUMROW - 1) % NUMROW];

        //bottom neigbour
        neighbours[3] = map[i][(j + NUMROW + 1) % NUMROW];

        //bottom left neighbour
        neighbours[4] =
            map[(i + NUMROW - 1) % NUMROW][(j + NUMROW + 1) % NUMROW];

        //bottom right neighbour
        neighbours[5] =
            map[(i + NUMROW + 1) % NUMROW][(j + NUMROW + 1) % NUMROW];

        //top left neighbour
        neighbours[6] =
            map[(i + NUMROW - 1) % NUMROW][(j + NUMROW - 1) % NUMROW];

        //top right neigbour
        neighbours[7] =
            map[(i + NUMROW + 1) % NUMROW][(j + NUMROW - 1) % NUMROW];

        int infections = 0;
        int dead = 0;

        for (p = 0; p < 8; p++)
        {
          if (neighbours[p] == 1)
          {
            infections++;
          }

          if (neighbours[p] == 2)
          {
            dead++;
          }
        }

        if (infections > 0 && map[i][j] == 0)
        {
          chance = 20.0;

          if (floor(rand() % 101) < chance)
          {
            //Person is infected

            tInfection++;
            tHealthy--;

            map[i][j] = 1;
            nextGen = 0;
          } //end of infections if statement
        } //end of chancing life

        if (map[i][j] == 1 && nextGen)
        {
          chance = 10.0;

          if (floor(rand() % 101) < chance)
          {
            //Person is dead
            tDead++;
            tHealthy--;
            map[i][j] = 2;
          }
        }

        if (map[i][j] == 1 && nextGen)
        {
          chance = 0.5;

          if (floor(rand() % 101) < chance)
          {
            tRecovered++;
            tDead--;
            map[i][j] = 3;
          }
        }
      }
    }
  }

  pthread_mutex_lock(&mutex);
  totalHealthy += tHealthy;
  totalDead += tDead;
  totalInfection += tInfection;
  totalRecovered += tRecovered;
  pthread_mutex_unlock(&mutex);

  //mutex barrier---------------------------
  pthread_mutex_lock(&barrier_mutex);
  barrCount2++;
  pthread_mutex_unlock(&barrier_mutex);
  while (barrCount2 < THREAD_COUNT)
    ;
  //----------------------------------------

  printf(
      "-------------------------------------------------\nThread %ld numbers:\nHealthy: %d\nDead: %d\nInfected: %d\nRecovered: %d\n",
      my_rank, totalHealthy, totalDead, totalInfection, totalRecovered);

  //every 50 generations create file with results
  if (genCount % 50 == 0)
  {
    //incrementing file name

    sem_post(&semaphores[dest]);

    sem_wait(&semaphores[my_rank]);

    snprintf(buffer, sizeof(char) * 32, "file%i.dat", k);

    //open the file
    fp = fopen(buffer, "r+");
    if (fp == NULL )
    {
      printf("I couldn't open file for writing.\n");
      exit(0);
    }

    int loop1, loop2;

    //outputting the array into the file
    for (loop1 = my_first_i; loop1 < my_last_i; loop1++)
    {
      for (loop2 = my_first_i; loop2 < my_last_i; loop2++)
      {
        fprintf(fp, "%d\t", map[loop1][loop2]);
      }
    }

    //close the file
    fclose(fp);

    k++;
  }

  return NULL ;
}

int main()
{

  //int map[1000][1000];
  //neighbours
  int totalHealthy = 0;
  int totalInfection = 0;
  int totalDead = 0;
  int totalRecovered = 0;
  double chance = 20.0;
  double start, finish, elapsed;

  int i, j, g, inf;
  int k = 0;

  //--------------Seed For Random Numbers-----------
  time_t t;
  /* Inititializes random number generator*/
  srand((unsigned) time(&t));
  //------------------------------------------------

  printf("Ebola spreading...\n");

  //start timer------------------
  GET_TIME(start);
  //-----------------------------

  //Thread code----------------------------------------------------------------------
  long thread;

  int semCount;
  for (semCount = 0; semCount < THREAD_COUNT; semCount++)
  {
    sem_init(&semaphores[semCount], 0, 1);
  }

  pthread_t *mythread_handle;

  mythread_handle = malloc(THREAD_COUNT * sizeof(pthread_t));

  for (thread = 0; thread < THREAD_COUNT; thread++)
  {
    pthread_create(&mythread_handle[thread], NULL, mythread_func,
        (void *) thread);
  }

  for (thread = 0; thread < THREAD_COUNT; thread++)
  {
    pthread_join(mythread_handle[thread], NULL );
  }

  pthread_mutex_destroy(&mutex);

  //----------------------------------------------------------------------------------
  //stop timer------------
  GET_TIME(finish);

  elapsed = finish - start;

  free(mythread_handle);

  printf("Time elapsed: %e seconds\n", elapsed);

  return 0;

}

timer.h ファイルは次のとおりです。

#ifndef _TIMER_H_
#define _TIMER_H_

#include <sys/time.h>

/* The argument now should be a double (not a pointer to a double) */
#define GET_TIME(now) { \
      struct timeval t; \
      gettimeofday(&t, NULL); \
      now = t.tv_sec + t.tv_usec/1000000.0; \
    }

#endif

どんな助けでも大歓迎です。ありがとう

4

1 に答える 1

0

*fp はグローバル変数であるため、各 therad は fopen で初期化し、作業が終了したら閉じようとします。*fp はスレッド間で共有されるため (共有されるべきではありません)、終了する前に各スレッドが *fp に格納されているファイル ハンドルを閉じようとし、別のスレッドによって既に閉じられているファイル ハンドルを複数のスレッドが閉じようとすると、二重解放が発生します。

関数ブロック内に *fp を配置して各スレッドに対してローカルにするか、 *fp 宣言の前に __thread を追加して各スレッド インスタンスに対してローカルにする必要があります。__thread FILE * fp;

于 2016-12-14T19:13:49.277 に答える