pthread_create后的段错误(

时间:2013-05-23 06:15:31

标签: c pointers struct segmentation-fault pthreads

我不能为我的生活弄清楚为什么这是分段错误。

中的分段错误
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);
}

plist和inlinks都是在头文件中设置的链接列表,所以我所做的就是获取这些和所有参数并使用它们来计算所有页面的“pageranks”并将它们存储到一个数组中。 plist存储页面结构(p),每个结构都存储一个链表(inlist)

我必须让它尽可能快地运行因此线程

它创建线程,然后在尝试遍历链表plist时发出seg错误。我的指针在哪里显然有问题,但我不能为我的生活弄明白。线程化这个程序一直是个噩梦。

如果有帮助,这是正常编写的函数,不会将所有参数都视为void * 基本上它在程序运行顺序函数时运行正常,但是当试图在并行函数中循环plist时会出现seg错误。

void get_ranks_seq(list* plist, double damp, double dampener, double rank_prev[], double rank_curr[])
{
    //loops through all the pages
    for (struct node* node = plist->head; node!=NULL; node=node->next)
    {
        //calling page from current node in list 
        page* p = node->page;
        //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)
            {
                sum += rank_prev[inNode->page->index] / inNode->page->noutlinks;     //calculations on current page using inlinks list associated with it
            }   
        }
        rank_curr[node->page->index] = damp + dampener*sum;
    }
}

对不起,如果这没有多大意义,任何帮助都会非常感激!


更新

我从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/pa‌​gerank) 
==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 – 

2 个答案:

答案 0 :(得分:0)

这个

args* data = malloc(sizeof(data));

只分配4(32位操作系统)或8字节(64字节操作系统),即指针的大小。

这很少,因为你想要args所需的字节数。

分配给少数人,在以后访问对象成员时会引发未定义的行为。

所以你可能想修改你的代码:

args* data = malloc(sizeof(*data));

更多的发行:

覆盖data

的值
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

当malloc()执行初始化内存时,下一行会引发未定义行为,因为访问单元化变量会:

for (i = 0; i < data->n_pages; i++)
{
  ...

答案 1 :(得分:0)

你做

args * data = (struct args *) q;

然后立即,

data = malloc(sizeof(struct args));

使data指向未初始化的内存,因此data->qlist在循环开始时为NULL。不确定你要做什么,但问题出在那里。