Ошибка сегментации с pthread_join

Вот функция, которая выдает 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, он показывает segault в pthread_join(). Я не могу понять, почему так происходит??? заранее спасибо


person nikhil    schedule 14.11.2010    source источник
comment
не отвечает на ваш вопрос, но поскольку вы используете С++, вы должны выделить свою переменную d с помощью: data *d = new data; это проще. Только не забудьте выпустить его с delete, а не с free.   -  person Evan Teran    schedule 14.11.2010


Ответы (2)


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

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

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

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

person Frédéric Hamidi    schedule 14.11.2010
comment
if(pthread_create(&thread,NULL,(void* ()(void))merge, (void*)d)==0) threadList.push_front(thread); - person nikhil; 14.11.2010
comment
я добавил указанную выше строку, но даже тогда она дает segfault - person nikhil; 14.11.2010
comment
@nikhil, threadList кажется глобальным. Может быть, он поврежден (или его итераторы признаны недействительными) одним из потоков? - person Frédéric Hamidi; 14.11.2010
comment
@nikhil, ну, например, если вы измените threadList из одного из ваших рабочих потоков, пока основной поток перебирает его, последует беспредел. - person Frédéric Hamidi; 14.11.2010
comment
@frederic: теперь он не выдает segfault. Но теперь элементы не сортируются ... в чем может быть причина ... И если я укажу диапазон как 1000, его сортировка ... но если я увеличу диапазон до 10000, он не будет отсортирован.? почему это могло быть? - person nikhil; 14.11.2010
comment
@nikhil, возможно, вы захотите сначала потратить некоторое время на отладку этого кода :) Если вы застряли, опубликуйте код своей функции merge(), возможно, в другом вопросе. - person Frédéric Hamidi; 14.11.2010
comment
@frederic: извините за беспокойство, но я много раз отлаживал его с помощью gdb, и кажется, что код правильный ... и я могу отправить вам всю программу, если вы хотите ее проверить. пожалуйста, помогите мне - person nikhil; 14.11.2010
comment
@nikhil, не нужно ничего отправлять по электронной почте, просто отредактируйте этот вопрос и добавьте код своей функции merge(), чтобы все могли его увидеть. Таким образом, если я не узнаю, что происходит, кто-то другой, вероятно, узнает :) - person Frédéric Hamidi; 14.11.2010
comment
@frederic: взгляните на функцию слияния, которую я добавил - person nikhil; 14.11.2010

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

person Paul Michalik    schedule 14.11.2010