使用 C 中的线程编译代码 'double free or corruption (out)' 时出错?

Error while compiling the code 'double free or corruption (out)' using threads in C?

我正在尝试使用 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

如有任何帮助,我们将不胜感激。谢谢

*fp 是一个全局变量,所以每个therad 都会用fopen 初始化它,并在完成工作后尝试关闭它。 *fp 在线程之间共享(不应该),因此每个线程在退出前都尝试关闭存储在 *fp 中的文件句柄,并且当多个线程试图关闭已被另一个线程关闭的文件句柄时会发生双重释放。

您必须将 *fp 放在函数块中以使其对每个线程都是本地的,或者在 *fp 声明之前添加 __thread 以使其对每个线程实例都是本地的。 __thread 文件 * fp;