Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

[C] ошибка сегментирования при создании пула потоков

40K
23 ноября 2009 года
himas
31 / / 13.11.2009
пытаюсь изучить предварительное создание пула потоков:
Код:
#include <pthread.h>
#include <stdio.h>

// число потоков в пуле
static int ntr = 3;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t condvar = PTHREAD_COND_INITIALIZER;

void *send(void* data)
{
    sched_yield();

    //
    printf("%d: %s \n", pthread_self(), (char*)data);
    //

    pthread_mutex_lock(&mutex);
    ntr++;
    pthread_cond_signal(&condvar);
    pthread_mutex_unlock(&mutex);
}

main()
{
    char *data = "test";

    // используем цикл, чтобы создать весь пул потоков
    while(1)
    {
        if(pthread_create(NULL, NULL, send, &data) == 0)
        {
            sched_yield();
            pthread_mutex_lock(&mutex);
            ntr--;
            while(ntr <= 0) pthread_cond_wait(&condvar, &mutex);
            pthread_mutex_unlock(&mutex);
        }
    }

}


компилю в gcc (-lpthread), запускаю - получаю:
Цитата:

Ошибка сегментирования



как исправить эту ошибку?

34K
23 ноября 2009 года
muturgan
96 / / 01.10.2009
Цитата: himas

компилю в gcc (-lpthread), запускаю - получаю:



Если у Вас это компилится, то Вы просто чародей. Откуда внутри функции send() компилятор узнает что такое data?
Также вызов pthread_create(NULL, NULL, &send, &data) произведён неправильно, третим параметром должен быть void*, а у Вас тут void**.
Используйте pthread_create(NULL, NULL, send, &data), и добавьте параметр в функцию, передаваемую в поток.

40K
23 ноября 2009 года
himas
31 / / 13.11.2009
Цитата: muturgan
Если у Вас это компилится, то Вы просто чародей. Откуда внутри функции send() компилятор узнает что такое data?
Также вызов pthread_create(NULL, NULL, &send, &data) произведён неправильно, третим параметром должен быть void*, а у Вас тут void**.
Используйте pthread_create(NULL, NULL, send, &data), и добавьте параметр в функцию, передаваемую в поток.


пока искал ошибку - испробовал множество вариантов, в том числе убирал всю работу с данными, отсюда и ошибка при копировании кода на форум. исправил первый пост.

насчет третьего параметра при вызове pthread_create - последовал вашему совету, однако данный шаг так и не устранил ошибку.

34K
23 ноября 2009 года
muturgan
96 / / 01.10.2009
Бегло просмотрев Ваш код, я тоже не заметил одну вещь=). data - это указатель на char, а в функцию вы передаёте &data, т.е. указатель на указатель, попробуйте заменить &data на (void*)data.
40K
23 ноября 2009 года
himas
31 / / 13.11.2009
Цитата: muturgan
Бегло просмотрев Ваш код, я тоже не заметил одну вещь=). data - это указатель на char, а в функцию вы передаёте &data, т.е. указатель на указатель, попробуйте заменить &data на (void*)data.


насколько я помню из учебной литературы унарная операция & выдает адрес объекта, почему вы считаете, что в pthread_create будет передаваться указатель на указатель (как в случае с &send, так и в случае с &data)? компилятор на первоначальный код не ругался

 
Код:
if(pthread_create(NULL, NULL, &send, &data) == 0)


на всякий случай попробовал ваш вариант - все так же ошибка сегментирования

попробовал поставить в начале функции main printf("0"); - при выполнении 0 не выводился, значит ли это, что ошибка сегментирования возникла еще до запуска моего кода?
34K
23 ноября 2009 года
muturgan
96 / / 01.10.2009
Цитата: himas
насколько я помню из учебной литературы унарная операция & выдает адрес объекта, почему вы считаете, что в pthread_create будет передаваться указатель на указатель (как в случае с &send, так и в случае с &data)? компилятор на первоначальный код не ругался


Смотрите. data - это указатель на char, т.е. это переменная, которая содержит в себе адрес ячейки памяти, в которой лежит переменная типа char. Действительно, Вы правы, что & - это унарный оператор, возвращающий адрес,но передавая &data, Вы передаёте адрес указателя, т.е. вовсе не адрес, по которому у Вас лежат данные.

Цитата: himas

значит ли это, что ошибка сегментирования возникла еще до запуска моего кода?


Нет, до запуска кода такая ошибка не могла возникнуть, попробуйте printf("0"); fflush(stdout);

34K
23 ноября 2009 года
muturgan
96 / / 01.10.2009
Ошибка сегментации у Вас возникает при вызове pthread_create(NULL, NULL, send, &data)

Первым параметром должен быть указатель на pthread_t, в переменную по этому адресу запишется id потока. Следующий код компилится и выполняется без ошибки сегментации:
Код:
#include <pthread.h>
#include <stdio.h>

// число потоков в пуле
static int ntr = 3;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t condvar = PTHREAD_COND_INITIALIZER;

void *send(void* data)
{
    sched_yield();

    //
    printf("%d: %s \n", pthread_self(), (char*)data);
    //

    pthread_mutex_lock(&mutex);
    ntr++;
    pthread_cond_signal(&condvar);
    pthread_mutex_unlock(&mutex);
}

main()
{
//  printf("0"); fflush(stdout);
    char *data = "test";
    int id;

    // используем цикл, чтобы создать весь пул потоков
    while(1)
    {
        if(pthread_create(&id, NULL, send, (void*)data) == 0)
        {
            sched_yield();
            pthread_mutex_lock(&mutex);
            ntr--;
            while(ntr <= 0) pthread_cond_wait(&condvar, &mutex);
            pthread_mutex_unlock(&mutex);
        }
    }

}
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог