Передача структур в качестве аргументов при использовании pthread_create () - PullRequest
17 голосов
/ 14 мая 2009

Я попытался передать структуру в качестве 4-го аргумента при использовании pthread_create() с чем-то вроде этого:

pthread_create(&tid1, NULL, calca, &t); //t is the struct

Теперь всякий раз, когда я пытаюсь получить доступ к переменным в структуре - t.a, t.b или t.c, я получаю сообщение об ошибке для члена в чем-то, не являющемся структурой или объединением.

Какой альтернативный метод я могу использовать для передачи структур в поток?

Ответы [ 7 ]

24 голосов
/ 14 мая 2009

Вы, вероятно, создаете структуру в том же объеме, что и pthread_create. Эта структура больше не будет действительной после выхода из этой области.

Попробуйте создать указатель на структуру в куче и передать указатель на структуру вашему потоку. Не забудьте удалить эту память где-нибудь (в ветке, если вы никогда больше не будете ее использовать - или когда она вам больше не понадобится).

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

Редактировать 14 мая 2009 @ 12:19 EST : Кроме того, как уже упоминали другие, вы должны привести свой параметр к правильному типу.

Если вы передаете переменную, которая является глобальной структурой (на которую вы, похоже, настаиваете), ваша функция потока должна будет привести к типу:

void my_thread_func(void* arg){
    my_struct foo = *((my_struct*)(arg)); /* Cast the void* to our struct type */
    /* Access foo.a, foo.b, foo.c, etc. here */
}

Или, если вы передаете указатель на вашу структуру:

void my_thread_func(void* arg){
    my_struct* foo = (my_struct*)arg; /* Cast the void* to our struct type */
    /* Access foo->a, foo->b, foo->c, etc. here */
}
2 голосов
/ 14 мая 2009

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

void my_thread_func(void* arg){
    my_struct foo = (my_struct)(*arg); /* Cast the void* to our struct type */
    /* Access foo.a, foo.b, foo.c, etc. here */
}
1 голос
/ 15 мая 2009
  1. Создать семафор

  2. Создайте еще одну структуру, состоящую из указателя на вашу структуру и дескриптора семафора

  3. Передать указатель на эту новую структуру в pthread_create

  4. В родительском потоке, то есть с именем pthread_create, дождитесь семафора

  5. В дочернем потоке скопируйте элементы вашей структуры в локальные переменные или сохраните их в другом месте

  6. В дочернем потоке сигнализировать семафор

  7. В родительском потоке закройте семафор

0 голосов
/ 25 июля 2014

my_struct foo = (my_struct) (* arg); неисправен пытаться my_struct * foo = (my_struct *) (arg);
И, int функция Вызов потока, убедитесь, что оно статично (чтобы указанная память не терялась в тумане)

0 голосов
/ 14 мая 2009

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

Я объявляю и определяю функцию потоков «обычным» способом:

void *ThreadFunction(sPARAMETERS *Params) {

  // do my threading stuff...

}

и когда я вызываю pthread_create, мне нужно использовать приведение:

pthread_create(&ThreadId,0,(void*(*)(void*)) &ThreadFunction,&Params);

Я почти никогда не забываю использовать & в параметрах, и компилятор позаботится о любых ошибках, которые я совершу на другом конце. Прекрасно работает и для обратных вызовов.

0 голосов
/ 14 мая 2009

Это сообщение об ошибке означает, что вы не разыменовываете указатель.

Вы говорите "t.a" вместо "t-> a"

[me@myhost ~]$ cat testitx.c
struct x {
        int a, b;
};

int main(int argc, char *argv[])
{
        struct x y, *z;

        z = &y;
        z.a = 10;
}
[me@myhost ~]$ cc -c testitx.c
testitx.c: In function `main':
testitx.c:10: error: request for member `a' in something not a structure or union
[me@myhost ~]$
0 голосов
/ 14 мая 2009

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

Просто не забудьте заблокировать переменные, которые являются общими для потоков.

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

...