执行并行版本时双重自由或损坏(fasttop)

时间:2014-05-05 04:37:23

标签: c++ map pthreads

我正在尝试使用pthread以并行方式实现串行算法。 以下是我写的代码 -

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>
#include <cmath>
#include <sys/time.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <ctime>
#include <vector>
#include <map>
#include <sstream>

using namespace std;
double similarity_score(char a,char b);
double find_array_max(double array[],int length);
void insert_at(char arr[], int n, int idx, char val);
void checkfile(int open, char filename[]);
void *main_algo(void* rank);
double valueChanger(int p1 , int p2);
string read_sequence(ifstream& f);

int ind;
double mu,delta;
double H_max = 0.;


int N_a;                     // get the actual lengths of the sequences
int N_b;

int** H;

int count_gap = 6;
int matrix_i = 1;
double temp[4];

char *nameof_seq_a;
char *nameof_seq_b;
string seq_a,seq_b;

 int bigCount;
 int start_i;
 int stop_i;
 int start_j;
 int stop_j;
 int stopSituation;
 int k;

    map<int,int> mymap;
    std::string strValue;
    std::stringstream out;
    std::stringstream out2;
    double value;

int main(int argc, char** argv){

  // read info from arguments
  if(argc!=5){
    cout<<"Give me the propen number of input arguments:"<<endl<<"1 : mu"<<endl;
    cout<<"2 : delta"<<endl<<"3 : filename sequence A"<<endl<<"4 : filename sequence B"<<endl;
    cout<<"5 : maximal length N of sequences"<<endl;exit(1);
  }
  mu    = atof(argv[1]);
  delta = atof(argv[2]);
  /////////////////////////////////
  // give it the filenames
  nameof_seq_a = argv[3];
  nameof_seq_b = argv[4];
  //int N_max = atoi(argv[5]);


  // read the sequences into two vectors:
  ifstream stream_seq_b;                      // first define the input-streams for seq_a and seq_b
  stream_seq_b.open(nameof_seq_b);            // the same for seq_b
  checkfile(! stream_seq_b,nameof_seq_b);
  seq_b = read_sequence(stream_seq_b);
  ifstream stream_seq_a;
  stream_seq_a.open(nameof_seq_a);            // open the file for input
  checkfile(! stream_seq_a,nameof_seq_a);     // check, whether the file was opened successfully
  seq_a = read_sequence(stream_seq_a);


  // string s_a=seq_a,s_b=seq_b;
  N_a = seq_a.length();                     // get the actual lengths of the sequences
  N_b = seq_b.length();

  cout<<"N_a length "<<N_a<<endl;
  cout<<"N_b length "<<N_b<<endl;
  ////////////////////////////////////////////////

  // initialize H
  int temp1 = N_a+1;
  int temp2 = N_b+1;

 // call to main algorithm
 bigCount = N_a;
 stopSituation = (N_a + N_b -1) /  count_gap;
 cout<<"--------Big Count----"<<bigCount<<endl;
 cout<<"--------stopSituation----"<<stopSituation<<endl;
 //cout<<"--------Matrix_i-------"<<matrix_i<<endl;
 while(matrix_i <= stopSituation+1){
    //cout<<"--------MATRIX_I----"<<matrix_i<<endl;
    pthread_t myThreads[matrix_i];
    for(k = 1; k < matrix_i +1 ; k++){
        if(k == 1){
            start_i = 1;
            stop_j = (count_gap * (matrix_i))+1;
        }
        else if(k == matrix_i){
            start_i = (count_gap * (k-1)) + 1;
            stop_j = count_gap +1;
        }
        else{
            start_i = (count_gap * (k-1)) + 1;
            stop_j = (count_gap * ((matrix_i - k)+1))+1;
        }

            start_j = (count_gap * (matrix_i - k))+1;
            stop_i = (count_gap * k)+1;

        //main_algo();
        pthread_create(&myThreads[k], NULL,main_algo, (void*)k);

        }
        //wait until all threads finish
        for(k = 1; k<matrix_i+1; k++){
            pthread_join(myThreads[k],NULL);
        }
   //sleep(1);
    if(matrix_i > 1)
    {

    }
    matrix_i++;
    }


  // Print the matrix H to the console
  cout<<"**************** Max is = "<<H_max<<endl;

mymap.clear();
} // END of main



/////////////////////////////////////////////////////////////////////////////
// auxiliary functions used by main:
/////////////////////////////////////////////////////////////////////////////


void checkfile(int open, char filename[]){

  if (open){cout << "Error: Can't open the file "<<filename<<endl;exit(1);}
  else cout<<"Opened file "<<filename<<endl;
}

/////////////////////////////////////////////////////////////////////////////
double valueChanger(int p1 , int p2){
    out.str(std::string());
    out2.str(std::string());
    out << p1;
    out2 << p2;
    strValue = out.str()+out2.str();
    double value_new = atoi(strValue.c_str());
    return value_new;
}

void *main_algo(void* rank){
//void main_algo(){


  // algorithm

  for(int i=start_i;i<stop_i;i++){
    if(i > N_a) {
    break;
    }
    for(int j=start_j;j<stop_j;j++){
    if(j > N_b){
    break;
    }
    int iCheck = i-1;
    int jCheck = j-1;

    value = valueChanger(iCheck , jCheck);
    //double myVal = H[iCheck][jCheck];
    double myVal;
    if ( mymap.find(value) == mymap.end() ) {
      // not found
    myVal = 0;
    } else {
      // found
    myVal = mymap.find(value)->second;
    }


    if(seq_a[i-1]==seq_b[j-1]){
    temp[0]=  myVal+1.0;
      }
    else{
         temp[0]= myVal-mu;
    }
    value = valueChanger(i-1 , j-1);
       if ( mymap.find(value) == mymap.end() ) {
      // not found
    temp[1] = 0;
    } else {
      // found
    temp[1] = mymap.find(value)->second-delta;
    }
    value = valueChanger(i , j-1);
     if ( mymap.find(value) == mymap.end() ) {
      // not found
    temp[2] = 0;
    } else {
      // found
    temp[2] = mymap.find(value)->second-delta;
    }

    temp[3] = 0.;
    value = valueChanger(i , j);
      mymap[value] = find_array_max(temp,4);

      if( H_max < mymap[value] ){
    H_max = mymap[value];
    }
     }
  }
cout<<"Done"<< my_rank<<endl;
}


double similarity_score(char a,char b){

  double result;
  if(a==b){
      result=1.;
    }
  else{
      result=-mu;
    }
  return result;
}

/////////////////////////////////////////////////////////////////////////////

double find_array_max(double array[],int length){

  double max = array[0];            // start with max = first element

  for(int i = 1; i<length; i++){
      if(array[i] > max){
    max = array[i];
      }
  }
  return max;                    // return highest value in array
}

/////////////////////////////////////////////////////////////////////////////

string read_sequence(ifstream& f)
{
  // overflows.
  string seq;
  char line[5000];
  while( f.good() )
    {
      f.getline(line,5000);
      //        cout << "Line:" << line << endl;
      if( line[0] == 0 || line[0]=='#' )
    continue;
      for(int i = 0; line[i] != 0; ++i)
    {
      int c = toupper(line[i]);
     // cout << char(c);
      if( c != 'A' && c != 'G' && c != 'C' && c != 'T' )
        continue;

      seq.push_back(char(c));
    }
    }
  return seq;
}

这里,当我执行这个程序时,我得到以下错误

*** Error in `./myProg': double free or corruption (fasttop): 0xb5300480 ***
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x767e2)[0xb74e67e2]
/lib/i386-linux-gnu/libc.so.6(+0x77530)[0xb74e7530]
/usr/lib/i386-linux-gnu/libstdc++.so.6(_ZdlPv+0x1f)[0xb7689aaf]
/usr/lib/i386-linux-gnu/libstdc++.so.6(_ZNSs4_Rep10_M_destroyERKSaIcE+0x1b)[0xb76ee5ab]
/usr/lib/i386-linux-gnu/libstdc++.so.6(+0xad5f0)[0xb76ee5f0]
/usr/lib/i386-linux-gnu/libstdc++.so.6(_ZNSs6assignERKSs+0x82)[0xb76efde2]
/usr/lib/i386-linux-gnu/libstdc++.so.6(_ZNSsaSERKSs+0x23)[0xb76efe33]
./myProg[0x80499dc]
./myProg[0x8049c2f]
/lib/i386-linux-gnu/libpthread.so.0(+0x6d78)[0xb7730d78]
/lib/i386-linux-gnu/libc.so.6(clone+0x5e)[0xb75613de]
======= Memory map: ========
*** Error in `./myProg': double free or corruption (fasttop): 0x0829c8f8 ***
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x767e2)[0xb74e67e2]
/lib/i386-linux-gnu/libc.so.6(+0x77530)[0xb74e7530]
/usr/lib/i386-linux-gnu/libstdc++.so.6(_ZdlPv+0x1f)[0xb7689aaf]
/usr/lib/i386-linux-gnu/libstdc++.so.6(_ZNSs4_Rep10_M_destroyERKSaIcE+0x1b)[0xb76ee5ab]
/usr/lib/i386-linux-gnu/libstdc++.so.6(+0xad5f0)[0xb76ee5f0]
/usr/lib/i386-linux-gnu/libstdc++.so.6(_ZNSsaSERKSs+0x23)[0xb76efe33]
./myProg[0x80499dc]
./myProg[0x8049aee]
/lib/i386-linux-gnu/libpthread.so.0(+0x6d78)[0xb7730d78]
Aborted (core dumped)

请随意复制并执行以下两个陈述 - 1)g ++ [name] .cpp -o [name] -lpthread 2)./ [name] 1 1 filetoread.txt filetoread2.txt

请更新我在编写代码时遇到的任何错误。 谢谢!!!!

2 个答案:

答案 0 :(得分:0)

您需要使用互斥锁(或其他锁定机制)保护任何非线程安全的变量(例如std :: map)。由于您正在使用pthread,请查看pthread_mutex_lock,pthread_mutex_unlock和pthread_mutex_destroy。

答案 1 :(得分:0)

如果您想要进行多线程处理,可以使用以下注释:

  1. (除非你真的需要)......(多线程带来了复杂性和问题的新世界)
  2. ....如果你真的需要,不要使用比处理器更多的线程(近年来这种情况因CPU /内核/超线程而变得混乱......但是我处理器的意思是硬件或虚拟化允许您并行运行的内容)(否则您将在操作系统/硬件级别进行调度争用)
  3. 锁定(互斥锁)全部公共数据访问....(否则会破坏您的常用数据)
  4. ....但尝试锁定最少的时间。 (因为每次你锁定它意味着你所有的线程都需要等待,他们什么都不做)。
  5. 除非您需要(因为锁定/解锁昂贵),否则不要使用锁
  6. 避免使用使用处理队列锁定(例如,通过线程传递命令或传递结果)。您可以在插入/删除队列时锁定,而不是在处理命令/结果时进行锁定。
  7. 通过将类似地图的单个结构(使用单个互斥锁)细分为数组的类似地图的结构(使用互斥锁数组)使用原始密钥的哈希值进行索引来避免锁定地图。而不是锁定所有线程,您将只锁定其中一些。
  8. 如果读者/作者之间存在不平衡,尝试读/写互斥以最大限度地减少争用。这将允许多个同时读者或一个作家。