C pthread_创建后出现Seg故障(
我一辈子都搞不明白为什么这是赛格断层 这是seg断层C pthread_创建后出现Seg故障(,c,pointers,struct,segmentation-fault,pthreads,C,Pointers,Struct,Segmentation Fault,Pthreads,我一辈子都搞不明白为什么这是赛格断层 这是seg断层 get_ranks_parallel 在线 for (struct node* node = data->plist->head; node!=NULL; node=node->next) 代码如下: typedef struct args args; struct args { list* qlist; double damps; double dampening; int j;
get_ranks_parallel
在线
for (struct node* node = data->plist->head; node!=NULL; node=node->next)
代码如下:
typedef struct args args;
struct args
{
list* qlist;
double damps;
double dampening;
int j;
int n_cores;
int n_pages;
double *rank_current;
double *rank_previous;
};
//int cond;
int i;
void pagerank(list* plist, int ncores, int npages, int nedges, double dampener)
{
int num_pages = npages;
args* data = malloc(sizeof(data));
//data = malloc(sizeof(args) + num_pages * sizeof(double));
data->damps = (1-dampener)/npages; //eg (1-0.85/4)
double damp = (1-dampener)/npages;
data->qlist = plist;
//store pageranks into arrays of doubles
double rank_prev[npages]; //previous ranks
double rank_curr[npages]; //current ranks
for (i = 0; i < npages; i++)
{
rank_prev[i] = (double)1/npages; //must cast either 1 or npages as a double to get output as a double
rank_curr[i] = (double)1/npages;
}
data->dampening = dampener; //for use inside parallel function
int stop = 1;
data->n_cores = ncores; //for use inside parallel function
int num_cores = data->n_cores;
pthread_t thread_id[num_cores];
while(stop == 1)
{
//if more than one core, parallelise
//else solve sequentially
if (ncores > 1)
{
pthread_mutex_init(&mutex_lock, NULL);
for (data->j = 0; data->j < num_cores; data->j++)
{
//thread_args[k] = k; //(plist, damp, dampener, rank_prev, rank_curr, i, num_cores)
pthread_create(&thread_id[data->j], NULL, &get_ranks_parallel, NULL);
}
for (data->j = 0; data->j < num_cores; data->j++)
{
pthread_join(thread_id[data->j], NULL);
}
for (i = 0; i < npages; i++)
{
rank_prev[i] = data->rank_previous[i];
rank_curr[i] = data->rank_current[i] ;
}
pthread_mutex_destroy(&mutex_lock);
}
else
{
get_ranks_seq(plist, damp, dampener, rank_prev, rank_curr);
}
stop = check_converge(rank_curr, rank_prev, npages);
update_prev(rank_curr, rank_prev, npages);
}
print_ranks(rank_curr, plist);
}
void * get_ranks_parallel(void * q)
{
args * data = (struct args *) q;
data = malloc(sizeof(struct args));
//store pageranks into arrays of doubles
data->rank_previous[data->n_pages]; //previous ranks
data->rank_current[data->n_pages]; //current ranks
//initialise_rank(rank_prev, rank_curr, npages); //initialise both rank arrays, setting all values a 1/N
for (i = 0; i < data->n_pages; i++)
{
data->rank_previous[i] = (double)1/data->n_pages; //must cast either 1 or npages as a double to get output as a double
data->rank_current[i] = (double)1/data->n_pages;
}
//loops through all the pages
for (struct node* node = data->qlist->head; node!=NULL; node=node->next)
{
//calling page from current node in list
page* p = node->page;
//thread will operate on rooms with index the same as thread id initially, then thread id +ncores, so all threads work on the same amount of rooms
if ((node->page->index) == data->j)
{
//check to make sure inlinks list is not empty
double sum = 0.0;
if (p->inlinks!=NULL)
{
//loops through the inlinks list that is associated with current page
for (struct node* inNode = p->inlinks->head; inNode != NULL; inNode = inNode->next)
{
pthread_mutex_lock(&mutex_lock);
sum += data->rank_previous[inNode->page->index] / inNode->page->noutlinks; //calculations on current page using inlinks list associated with it
pthread_mutex_unlock(&mutex_lock);
}
}
pthread_mutex_lock(&mutex_lock);
data->rank_current[node->page->index] = data->damps + data->dampening*sum;
pthread_mutex_unlock(&mutex_lock);
}
pthread_mutex_lock(&mutex_lock);
data->j += data->n_cores;
pthread_mutex_unlock(&mutex_lock);
}
//free(args);
}
对不起,如果这没有多大意义,任何帮助都将不胜感激
更新: 我从valgrind得到这个错误:
==5337== Thread 2:
==5337== Invalid read of size 4
==5337== at 0x4017A8: get_ranks_parallel (in /.automount/net/ufiler5/u3/cs1/lsin8526/comp2129_2013/assignment4/assignment4/pagerank)
==5337== by 0x3252607D14: start_thread (in /usr/lib64/libpthread-2.16.so)
==5337== by 0x3251EF246C: clone (in /usr/lib64/libc-2.16.so)
==5337== Address 0x20 is not stack'd, malloc'd or (recently) free'd –
这个
仅分配指针大小的4(32位操作系统)或8字节(64字节操作系统)
这非常少,因为您需要的字节数与args
所需的字节数相同
分配给少数成员会引发未定义的行为,或在以后访问对象成员时引发未定义的行为
因此,您可能希望对代码进行如下修改:
args* data = malloc(sizeof(*data));
还有一些疑问: 覆盖
数据的值
:
args * data = (struct args *) q;
data = malloc(sizeof(struct args));
//store pageranks into arrays of doubles
无用代码(不执行任何操作):
正如malloc()不初始化内存一样,下一行会引发未定义的行为,就像访问单元化变量一样:
for (i = 0; i < data->n_pages; i++)
{
...
(i=0;i
{
...
你知道吗
args * data = (struct args *) q;
然后紧接着
data = malloc(sizeof(struct args));
使
data
指向未初始化的内存,因此data->qlist
在循环开始时是NULL
。不确定您试图做什么,但这是您的问题。我打赌data
、plist
或节点
指向无效内存,或者干脆是NULL
。Valgrind是您的选择朋友。这不应该是args*data=malloc(sizeof(data));
beargs*data=malloc(sizeof(*data))
plist和node应该很好,因为它在函数的顺序版本中工作得很好。我把所有参数都放到了结构中,所以函数可以以某种方式传递到pthread\u create…请在调试设置为on的情况下编译代码(通常-g
)。然后valgrind甚至调试器可能会准确地告诉您出错的行。无论如何,这样的在线调试并不适合,因此,这太本地化了,作为一个问题,投票关闭。不幸的是,这并没有解决它。它仍在创建线程并立即seg faultingCrap无法相信我没有分配n_页面。不是吗考虑到这个问题,在修复了未初始化的值之后,我从valgrind得到了这个错误:==5337==线程2:==5337==大小为4的无效读取==5337==在0x4017A8:get_ranks_parallel(in/.automount/net/ufiler5/u3/cs1/lsin8526/comp2129_2013/assignment4/assignment4/pagerank)==5337==通过0x3252607D14:start_线程(在/usr/lib64/libpthread-2.16.so中)=5337==by 0x3251EF246C:clone(在/usr/lib64/libc-2.16.so中)==5337==Address 0x20不是stack'd、malloc'd或(最近)free'd“…在0x4017A8:get_ranks_parallel…`“这是在OP中发布的代码中的位置?”…因此data->qlist为NULL…”它可以是任何值,如malloc()
不会将分配的内存设置为0
。哦,好的,这是有意义的。但是仍然存在seg故障:(
for (i = 0; i < data->n_pages; i++)
{
...
args * data = (struct args *) q;
data = malloc(sizeof(struct args));