由于参数

时间:2015-06-30 15:15:49

标签: c multithreading pthread-join

我遇到了多线程程序的奇怪问题,我只报告部分代码。当我尝试运行它时,我收到分段错误错误。使用gdb和valingrind我能够发现问题是当我尝试取消引用info时,例如在for(i=0; i<info->subm_n; i++)中。 最奇怪的是,如果我在info=(c_args*)a之后进行转换strncpy(),那么只有当收集器的线程退出时它才会出现分段错误。 我使用的是64位操作系统而且我已经读过,这有时可能会在void*投射到pthread_create()时出现问题,我甚至不知道是否会这样做#39}是这样的。 任何人有任何想法? 的 P.S。使用大写字母的系统调用只是对函数的重新定义,我也测试失败

typedef struct collector_arguments{
  int subm_n;
  int chronon;
   planet_t *p;
}c_args;


static void* collector(void* a) {
  int fd_skt,fd_sincro,tmp,i=0;
   c_args *info;
   struct sockaddr_un sa;
   info=(c_args*) a;

  strncpy(sa.sun_path,"visual.sck" ,MAXPATH);
  sa.sun_family=AF_UNIX;

  if((fd_sincro=open("SINCRO",O_RDWR))==-1) {
      perror("collector unable to open SINCRO fifo");fflush(stdout);
      pthread_exit(&errno);
   }
  for(i=0; i<info->subm_n; i++) {
    if (read(fd_sincro,&tmp,sizeof(int))==-1){
         perror ("collector Unable to read");fflush(stdout);
         pthread_exit(&errno);
    }
    fd_skt=Socket(AF_UNIX,SOCK_STREAM,0);
    while (connect(fd_skt,(struct sockaddr*)&sa, sizeof(sa)) == -1 ) {
        if ( errno == ENOENT )  sleep(1);
        else {
            perror ("client unable to connect to socket");fflush(stdout);
            pthread_exit (&errno);
        }
    }
    Write(fd_skt,&i,sizeof(int));
    Close(fd_skt);
  }
  Close(fd_sincro);
  pthread_exit((void*) 0);
}




static pthread_mutex_t fifo_mtx = PTHREAD_MUTEX_INITIALIZER;

static void* dispatcher(void* a) {
coordinate *c;
wator_t* w;
int i,j,fifo;
pthread_t tid_collector;

c_args *info=malloc (sizeof(c_args));
w=(wator_t*) a; 
c=(coordinate*) malloc(sizeof(coordinate));
c->numr=2;
c->numc=2;
while ( ((w->plan->nrow / c->numr) * (w->plan->ncol / c->numc))>NWORK_DEF && (w->plan->nrow > 2*c->numr) && (w->plan->ncol > 2*c->numc) ){
    if ( (w->plan->nrow / c->numr) >= (w->plan->ncol / c->numc) )       
        c->numr=c->numr*2;
    else 
        c->numc=c->numc*2;
    }


if ((w->plan->nrow % c->numr)==0) i=(w->plan->nrow / c->numr);
else i=(w->plan->nrow / c->numr)+1;
if ((w->plan->ncol % c->numc)==0) j=(w->plan->ncol / c->numc);
else j=(w->plan->ncol / c->numc)+1;
info->subm_n=i*j;
info->chronon=0;
info->p=w->plan;
while(1){
    reset_updated(w);
    (info->chronon)++;

    Pt_create( &tid_collector, NULL,&collector,(void*) info);

    for(i=0; i< w->plan->nrow; i+=c->numr)
        for(j=0; j< w->plan->ncol; j+=c->numc){     
            if((fifo=open("FIFO",O_WRONLY))==-1){
                perror("dispatcher unable to open FIFO");fflush(stdout);
                pthread_exit(&errno);
                }
            c->rowi=i;
            c->coli=j;
            Write(fifo, c, sizeof(*c));
            Close(fifo);
            }
    i=( (i/c->numr) * (j/c->numc) );
    Pt_join( tid_collector,NULL);
    }
return NULL;
}

2 个答案:

答案 0 :(得分:2)

strncpy(sa.sun_path,"visual.sck" ,MAXPATH);

什么是MAXPATH

不要忘记strncpy()将填零MAXPATH char

在linux上sun_path被定义为108个字符长,所以如果MAXPATH大于那个(或者系统上使用的任何值)那么你处于未定义行为的领域 - 用这个错误类型 - 通常意味着内存损坏最终导致seg错误:

#define UNIX_PATH_MAX   108

struct sockaddr_un {
    __kernel_sa_family_t sun_family; /* AF_UNIX */
    char sun_path[UNIX_PATH_MAX];   /* pathname */
};

答案 1 :(得分:-1)

不是答案,但这段代码是什么:

for(i=0; i<info->subm_n; i++) {
    if (read(fd_sincro,&tmp,sizeof(int))==-1){
         perror ("collector Unable to read");fflush(stdout);
         pthread_exit(&errno);
    }

为什么唐·约翰fseek然后只读一个字节?或读取至少4k(甚至更好的块大小字节,然后根据需要进行...