创建共享库时检测到分段错误/ glibc

量子态

编辑-我尝试使用gcc-4.8.1,但仍然存在相同的错误.-------------我正在尝试实现一个通过共享库使用pthreads的简单矩阵乘法示例。但是,当我尝试创建共享库时出现此错误:

g++ -shared -o libMatmul.so matmul.o 
collect2: ld terminated with signal 11 [Segmentation fault], core dumped

这是我正在使用的代码:matmul.h:

#ifndef matmul_h__
#define matmul_h__
#define SIZE 10 

typedef struct {

int dim;
int slice;
} matThread;

int num_thrd;
int A[SIZE][SIZE], B[SIZE][SIZE], C[SIZE][SIZE];
int m[SIZE][SIZE];
extern void init_matrix(int m[SIZE][SIZE]);
extern void print_matrix(int m[SIZE][SIZE]);
extern void* multiply(void* matThread);

#endif

matmul.c:

extern "C"
 {
    #include <pthread.h>
    #include <unistd.h>
 }
#include <iostream>
#include "matmul.h"

using namespace std ;
matThread* s=NULL;
// initialize a matrix
void init_matrix(int m[SIZE][SIZE])
{
  int i, j, val = 0;
  for (i = 0; i < SIZE; i++)
  for (j = 0; j < SIZE; j++)
  m[i][j] = val++;
}

void print_matrix(int m[SIZE][SIZE])
{
  int i, j;
  for (i = 0; i < SIZE; i++) {
    cout<<"\n\t|" ;
    for (j = 0; j < SIZE; j++)
      cout<<m[i][j] ;
      cout<<"|";
    }
}
 // thread function: taking "slice" as its argument
void* multiply(void* param)
{
  matThread* s = (matThread*)param;   // retrive the slice info
  int slice1=s->slice;
  int D= s->dim=10;
  int from = (slice1 * D)/num_thrd; // note that this 'slicing' works fine
  int to = ((slice1+1) * D)/num_thrd; // even if SIZE is not divisible by num_thrd
  int i,j,k;
   cout<<"computing slice  " << slice1<<" from row "<< from<< " to " <<to-1<<endl;
  for (i = from; i < to; i++)
  {  
    for (j = 0; j < D; j++)
    {
      C[i][j] = 0;
      for ( k = 0; k < D; k++)
      C[i][j] += A[i][k]*B[k][j];
    }
   }
  cout<<" finished slice "<<slice1<<endl;
  return NULL;
 }

main.c:

extern "C"
{
#include <pthread.h>
#include <unistd.h>
}
#include <iostream>
#include "matmul.h"
using namespace std;

// Size by SIZE matrices
// number of threads
matThread* parm=NULL;

int main(int argc, char* argv[])
{
  pthread_t* thread;  // pointer to a group of threads
  int i;
   if (argc!=2)
  {
   cout<<"Usage:"<< argv[0]<<" number_of_threads"<<endl;
   exit(-1);
  }
  num_thrd = atoi(argv[1]);
  init_matrix(A);
  init_matrix(B);
  thread = (pthread_t*) malloc(num_thrd*sizeof(pthread_t));
  matThread *parm = new matThread();
  for (i = 0; i < num_thrd; i++)
  {
parm->slice=i;
    // creates each thread working on its own slice of i
    if (pthread_create (&thread[i], NULL, multiply, (void*)parm) != 0)
    {
      cerr<<"Can't create thread"<<endl;
      free(thread);
      exit(-1);
    }
  }
 for (i = 1; i < num_thrd; i++)
  pthread_join (thread[i], NULL);
   cout<<"\n\n";
   print_matrix(A);
   cout<<"\n\n\t *"<<endl;
   print_matrix(B);
   cout<<"\n\n\t="<<endl;
   print_matrix(C);
   cout<<"\n\n";
   free(thread);

  return 0;

}

我使用的命令是:g ++ -c -Wall -fPIC matmul.cpp -o matmul.o和g ++ -shared -o libMatmul.so matmul.o代码看起来可能很少,因为我在A中传递了SIZE(dim)当它已经在#define中时,struct,但这就是我想要实现它的方式。它是我正在做的一个更大项目的测试程序。任何帮助是极大的赞赏!提前致谢。

txtechhelp

首先,您混用了许多C和C ++习惯用法(例如,调用freenew),并且没有使用任何C ++库/ STL功能(例如Astd::vectorstd::listC数组,而不是C数组),因此虽然代码在技术上是“有效(减去一些错误),这样混合C和C ++并不是一个好习惯,C和C ++之间有许多小的特质差异(例如语法,编译和链接差异),如果不清楚,可能会使代码混乱的意图。

话虽如此,我对您的代码进行了一些更改以使其C++98兼容(并修复错误):

开始matmul.h

#ifndef matmul_h__
#define matmul_h__
#define SIZE 10
#include <pthread.h>

typedef struct matThread {
    int slice;
    int dim;
    pthread_t handle;

    matThread() : slice(0), dim(0), handle(0) {}
    matThread(int s) : slice(s), dim(0), handle(0) {}
    matThread(int s, int d) : slice(s), dim(d), handle(0) {}
} matThread;

// explicitly define as extern (for clarity)
extern int num_thrd;
extern int A[SIZE][SIZE];
extern int B[SIZE][SIZE];
extern int C[SIZE][SIZE];
extern void init_matrix(int m[][SIZE]);
extern void print_matrix(int m[][SIZE]);
extern void* multiply(void* matThread);

#endif

开始matmul.cpp

#include <iostream> // <stdio.h>
#include "matmul.h"

int num_thrd = 1;
int A[SIZE][SIZE];
int B[SIZE][SIZE];
int C[SIZE][SIZE];

// initialize a matrix
void init_matrix(int m[][SIZE])
{
    int i, j, val;
    for (i = 0, val = -1; i < SIZE; i++) {
        for (j = 0; j < SIZE; j++) {
            m[i][j] = ++val;
        }
    }
}

void print_matrix(int m[][SIZE])
{
    int i, j;
    for (i = 0; i < SIZE; i++) {
        std::cout << "\n\t|"; // printf
        for (j = 0; j < SIZE; j++) {
            std::cout << m[i][j];
        }
        std::cout << "|"; // printf
    }
}

// thread function: taking "slice" as its argument
void* multiply(void* param)
{
    matThread* s = (matThread*)param;   // retrive the slice info
    int slice1 = s->slice;
    int D = s->dim = 10;
    int from = (slice1 * D) / num_thrd; // note that this 'slicing' works fine
    int to = ((slice1+1) * D) / num_thrd; // even if SIZE is not divisible by num_thrd
    int i, j, k;
    std::cout << "computing slice " << slice1 << " from row " << from << " to " << (to-1) << std::endl; // printf
    for (i = from; i < to; i++) {
        for (j = 0; j < D; j++) {
            C[i][j] = 0;
            for ( k = 0; k < D; k++) {
                C[i][j] += A[i][k]*B[k][j];
            }
        }
    }
    std::cout << " finished slice " << slice1 << std::endl; // printf
    return NULL;
}

开始main.cpp

#include <iostream>
#include <cstdlib> // atoi .. if C++11, you could use std::stoi in <string>
#include "matmul.h"

int main(int argc, char** argv)
{
    if (argc != 2) {
        std::cout << "Usage: " << argv[0] << " number_of_threads" << std::endl;
        return -1;
    } else {
        num_thrd = std::atoi(argv[1]);
    }
    matThread mt[num_thrd];
    int i = 0;
    init_matrix(A);
    init_matrix(B);
    for (i = 0; i < num_thrd; i++) {
        mt[i].slice = i;
        // creates each thread working on its own slice of i
        if (pthread_create(&mt[i].handle, NULL, &multiply, static_cast<void*>(&mt[i])) != 0) {
            printf("Can't create thread\n");
            return -1;
        }
    }
    for (i = 0; i < num_thrd; i++) {
        pthread_join(mt[i].handle, NULL);
    }
    std::cout << "\n\n";
    print_matrix(A);
    std::cout << "\n\n\t *\n";
    print_matrix(B);
    std::cout << "\n\n\t=\n";
    print_matrix(C);
    std::cout << "\n\n";
    return 0;
}

要编译和使用它,您需要执行以下命令:

g++ -c -Wall -fPIC matmul.cpp -o matmul.o
g++ -shared -Wl,-soname,libMatmul.so -o libMatmul.so.1 matmul.o
ln /full/path/to/libMatmul.so.1 /usr/lib/libMatmul.so
g++ main.cpp -o matmul -Wall -L. -lMatmul -pthread

请注意,为了使您的系统能够查找并链接到刚刚创建的共享库,您需要确保它位于发行版的lib文件夹中(如/usr/lib/)。您可以复制/移动/创建链接(ln -s如果无法进行硬链接,则可以通过它创建符号链接),如果您不想复制/移动/链接,则还可以确保自己LD_LIBRARY_PATH是正确设置为包含构建目录。

就像我说的; 你的代码是不是天生C ++除了少数print语句(std::cout等),以及改变C ++代码(std::coutprintf与例如其他一些小事情),你可以编译这个标准C99代码。我不是100%不确定共享库的其余部分将如何设计,因此我没有更改lib代码的结构(即您具有的功能),但是如果您希望此代码为“更多C ++”(即使用类/命名空间,STL等),您基本上需要重新设计代码,但是鉴于代码的上下文,除非您有特殊需要,否则我认为这不是绝对必要的。

希望能对您有所帮助。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章