Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 由于一个参数,多线程程序出现分段错误_C_Multithreading_Pthread Join - Fatal编程技术网

C 由于一个参数,多线程程序出现分段错误

C 由于一个参数,多线程程序出现分段错误,c,multithreading,pthread-join,C,Multithreading,Pthread Join,我有一个奇怪的多线程程序的问题,我只报告部分代码。当我尝试运行它时,我收到一个分段错误。使用gdb和valingrind,我发现问题出在我尝试取消对信息的引用时,比如在中(I=0;isubm\n;I++)。 最奇怪的是,如果我在strncpy()之后设置castinfo=(c_args*)a,它只有在收集器的线程退出时才会出现分段错误。 我使用的是64位操作系统,我读到在pthread_create()中强制转换为void*时,有时会出现问题,我甚至不知道是否是这样。 有人知道吗? P.S.带有

我有一个奇怪的多线程程序的问题,我只报告部分代码。当我尝试运行它时,我收到一个分段错误。使用gdb和valingrind,我发现问题出在我尝试取消对
信息的引用时,比如在
中(I=0;isubm\n;I++)
。 最奇怪的是,如果我在
strncpy()
之后设置cast
info=(c_args*)a
,它只有在收集器的线程退出时才会出现分段错误。 我使用的是64位操作系统,我读到在
pthread_create()
中强制转换为
void*
时,有时会出现问题,我甚至不知道是否是这样。 有人知道吗? P.S.带有大写字母的系统调用只是对我测试失败的witch中函数的重新定义

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;
}
typedef结构收集器_参数{
国际货币基金组织;
国际时钟;
行星_t*p;
}c_args;
静态void*收集器(void*a){
int fd_skt,fd_sincro,tmp,i=0;
c_args*信息;
结构sockaddr_un sa;
信息=(c_args*)a;
strncpy(sa.sun_path,“visual.sck”,MAXPATH);
sa.sun_family=AF_UNIX;
如果((fd_sincro=open(“sincro”,O_RDWR))=-1){
perror(“收集器无法打开SINCRO fifo”);fflush(stdout);
pthread_退出(&errno);
}
对于(i=0;isubm\n;i++){
如果(读取(fd_sincro和tmp,sizeof(int))=-1){
perror(“收集器无法读取”);fflush(标准输出);
pthread_退出(&errno);
}
fd_skt=Socket(AF_UNIX,SOCK_流,0);
while(connect(fd_skt,(struct sockaddr*)和sa,sizeof(sa))=-1){
如果(errno==enoint)睡眠(1);
否则{
perror(“客户端无法连接到套接字”);fflush(stdout);
pthread_退出(&errno);
}
}
写入(fd_skt,&i,sizeof(int));
关闭(fd_skt);
}
关闭(fd_sincro);
pthread_exit((void*)0);
}
静态pthread\u mutex\u t fifo\u mtx=pthread\u mutex\u初始值设定项;
静态void*dispatcher(void*a){
坐标*c;
瓦托瓦;
国际先进先出;
pthread_t tid_收集器;
c_args*info=malloc(sizeof(c_args));
w=(瓦特*)a;
c=(坐标*)malloc(sizeof(坐标));
c->numr=2;
c->numc=2;
而(((w->plan->nrow/c->numr)*(w->plan->ncol/c->numc))>NWORK_DEF&&(w->plan->nrow>2*c->numr)&&(w->plan->ncol>2*c->numc)){
如果((w->plan->nrow/c->numr)=(w->plan->ncol/c->numc))
c->numr=c->numr*2;
其他的
c->numc=c->numc*2;
}
如果((w->plan->nrow%c->numr)=0)i=(w->plan->nrow/c->numr);
否则i=(w->plan->nrow/c->numr)+1;
如果((w->plan->ncol%c->numc)==0)j=(w->plan->ncol/c->numc);
否则j=(w->plan->ncol/c->numc)+1;
信息->子模块n=i*j;
信息->计时=0;
信息->p=w->计划;
而(1){
重置_更新(w);
(信息->计时)+;
Pt_创建(&tid_收集器,NULL,&collector,(void*)信息);
对于(i=0;iplan->nrow;i+=c->numr)
对于(j=0;jplan->ncol;j+=c->numc){
如果((fifo=打开(“fifo”,仅限O_WRONLY))=-1){
perror(“调度程序无法打开FIFO”);fflush(stdout);
pthread_退出(&errno);
}
c->rowi=i;
c->coli=j;
写入(fifo、c、sizeof(*c));
关闭(fifo);
}
i=((i/c->numr)*(j/c->numc));
Pt_join(tid_收集器,NULL);
}
返回NULL;
}
strncpy(sa.sun_path,“visual.sck”,MAXPATH)

什么是
MAXPATH

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

在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 */
};

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

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);
    }
(i=0;isubm\n;i++)的
{
如果(读取(fd_sincro和tmp,sizeof(int))=-1){
perror(“收集器无法读取”);fflush(标准输出);
pthread_退出(&errno);
}

如果您认为这是内存泄漏、堆栈损坏等问题,为什么不先查看一个字节,然后只读取一个字节?或者至少读取4k(或者更好的块大小字节,然后相应地访问…

。为什么不尝试valgrind之类的内存调试器(请参阅)


它至少会告诉您是否存在内存问题、数组末尾以外的写入等问题。

我首先注意到的一件事是,您正在使用pthread\u t tid\u收集器,然后将其传递给每个pthread\u创建的线程。每次这样做时,您都会破坏该线程标识符,并且无法再pthread\u加入该特定线程,只有最新创建的线程。您应该创建一个pthread_t数组,并在每次迭代时递增传递给pthread_create的索引。我在复制代码时出错,在连接while结束后,以这种方式,每次执行while块时只创建并连接一个收集器,而不是创建多个coLlector。对于显示的代码,开始/结束大括号的数量不匹配。请修复此问题,以及此“奇怪”至少是不一致的缩进。似乎某些操作破坏了堆栈。尝试观察,例如,在gdb下执行期间的
info
变量。@user2676680,他在循环的每个迭代结束时加入创建的线程,因此他不需要一次记住多个线程标识符。这个问题是有效的,但是所有这些都不是有效答案。此外,
strncpy()
不会将任何内容归零。'src的长度小于n时,strncpy()将额外的空字节写入dest,以确保总共写入n个字节。“有一个
#define MAXPATH 200
我没有显示,但我不明白这是怎么一个问题。我的问题是,
strncpy()
确实存在。但这仍然不是一个答案,尽管它可以