Ошибка сегментации с pthread_join - PullRequest
2 голосов
/ 14 ноября 2010

Вот функция, которая дает segfault в pthread_join:


void call_merge()    
{    
    int no_runs = No_sub_seq;    
        int no_joins=no_runs-1;
    int magic1=0,j=0,inc = 1;
    int temp_runs = no_runs/2;        
    int i,k;
    while(temp_runs!=0)    
    {
        magic1=0;
        std::list<pthread_t> threadList;
        pthread_t thread;
        for(i=0;i<=temp_runs-1;i++)
        {
                    if((magic1 + inc) <= no_joins)    
                    {
                        data *d=(data *)malloc(sizeof(data));

                        d->a=magic1;
                        d->b=magic1+inc;
                        d->c=inc;
                         pthread_create(&thread,NULL,(void* (*)(void*))merge, (void*)d);  
                         threadList.push_front(thread);

                    }
                    magic1 = magic1 + (inc * 2); 
        }
        std::list<pthread_t>::iterator m;
        for(m=threadList.begin();m!=threadList.end();m++)
                pthread_join(*m,NULL);
        if((no_runs % 2) != 0)
            temp_runs++;    
        no_runs = temp_runs;
        temp_runs = no_runs/2;     
        inc = inc * 2;
        }
}

вот функция слияния


void merge(void *param)
{
    data *d=(data *)param;

    int low=Sq[d->a],high;

    int mid=Sq[d->b]-1;

    if(Sq[d->b + d->c]==0)
        high=size-1;
    else
        high=Sq[d->b + d->c]-1;

    int k;

    int i=0;
    int j=low;

    while(j<=mid)
        b[i++]=a[j++];

    i=0; k=low;
    while (k<j && j<=high)
        if (b[i]<=a[j])
            a[k++]=b[i++];
        else
            a[k++]=a[j++];

    while (k<j)
        a[k++]=b[i++];

}

функция слияния, вызываемая в приведенном выше коде, просто объединяет подмассивы, переданные с использованием параметров d-> a, d-> b, d-> c. и нет никакого кода потока, написанного в функции слияния. Вышеприведенная программа отлично работает, когда нет потоков, и выдает отсортированную последовательность входного массива. Когда я пытался отладить это с помощью gdb, в pthread_join () показывается сегмент. Я не могу понять, почему это происходит так ??? заранее спасибо

Ответы [ 2 ]

2 голосов
/ 14 ноября 2010

Один из ваших вызовов pthread_create () , вероятно, завершается неудачей, например, потому что вы превышаете ограничение на общее количество потоков на процесс.

В этом случае threadсодержит неопределенное значение.Поскольку вы игнорируете ошибку, вы продолжаете и сохраняете это неопределенное значение в своем списке, а затем вызываете pthread_join () для него позже, что приводит к segfault.

EDIT: Теперь, когда вы обрабатываете ошибки из pthread_create(), segfault больше не существует, но некоторые ваши потоки по-прежнему не создаются, поэтому они не могут выполнять свою работу.Вот почему ваш код работает с диапазоном 1000, но не с диапазоном 10000.

Ваш дизайн хорошо подходит для пула потоков , то есть порождает фиксированное числопотоков и дать им больше работы, как только они закончат свои текущие задачи.См. здесь или там для реализации пула с использованием потоков POSIX.

0 голосов
/ 14 ноября 2010

В какой области вы определяете объект threadList? Вы push_front вновь создали потоки в списке, но в вашем коде я не вижу ни явного erase соединенных потоков, ни удаления RAII всего списка потоков. Поскольку вы перебираете весь список потоков, вы, вероятно, вызываете pthread_join несколько раз для уже отмененных потоков ...

...