Передача нескольких аргументов потоку в C (pthread_create) - PullRequest
6 голосов
/ 29 июня 2011

Я пытаюсь передать 2 беззнаковых целых во вновь созданный поток в C (используя pthread_create ()), но ни массив из 2 целых чисел, ни структура не работают.

// In my socket file

struct dimension {
    unsigned int width;
    unsigned int height;
};

unsigned int width, height;

void setUpSocket(void* dimension) {

    struct dimension* dim = (struct dimension*) dimension;

    width = dim->width;
    height = dim->height;

    printf("\n\nWidth: %d, Height: %d\n\n", width, height);

}

// In main.cpp

// Pass a struct in pthread_create
struct dimension dim;
dim.width = w;
dim.height = h;

pthread_create(&ph, &attr, (void * (*)(void *)) setUpSocket, (void *) &dim);

Перед вызовом pthread_create, dim.width и dim.height верны. В моем файле сокета установлена ​​только ширина, высота 0, и я не понимаю, почему.

Кто-нибудь знает, что не так, пожалуйста и как это исправить?

Большое спасибо.

Ответы [ 4 ]

11 голосов
/ 29 июня 2011

Способ передачи аргументов должен работать нормально, , пока dim не выделено в стеке . Если он находится в стеке, он может быть освобожден до того, как новый поток сможет запустить, что приведет к неопределенному поведению. Если вы создаете только один поток, вы можете использовать глобальную переменную, но лучшая альтернатива - разместить ее в куче.

Кроме того, вы должны не приводить указатель функции: это неопределенное поведение (и фактически может произойти сбой из-за спекулятивного выполнения в архитектуре IA64 ). Вы должны объявить вашу потоковую процедуру для возврата void* и избегать приведения указателя на функцию:

void *setUpSocket(void* dimension) {

    struct dimension* dim = (struct dimension*) dimension;

    width = dim->width;
    height = dim->height;
    // Don't leak the memory
    free(dim);

    printf("\n\nWidth: %d, Height: %d\n\n", width, height);

    return 0;
}

// In main.cpp

// Pass a struct in pthread_create (NOT on the stack)
struct dimension *dim = malloc(sizeof(struct dimension));
dim->width = w;
dim->height = h;

pthread_create(&ph, &attr, setUpSocket, dim);
1 голос
/ 30 июня 2011

Насколько большой может быть ширина и высота?Если бы не очень большой, я бы сделал что-то вроде этого:

 pthread_create(&ph, &attr, setUpSocket, (void *)(65536*height+width));
0 голосов
/ 29 июня 2011

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

0 голосов
/ 29 июня 2011

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

...