Мне нужно передать несколько аргументов функции, которую я хотел бы вызвать в отдельном потоке. Я читал, что типичный способ сделать это - определить структуру, передать функции указатель на нее и разыменовать ее для аргументов. Однако я не могу заставить это работать:
#include <stdio.h>
#include <pthread.h>
struct arg_struct {
int arg1;
int arg2;
};
void *print_the_arguments(void *arguments)
{
struct arg_struct *args = (struct arg_struct *)args;
printf("%d\n", args -> arg1);
printf("%d\n", args -> arg2);
pthread_exit(NULL);
return NULL;
}
int main()
{
pthread_t some_thread;
struct arg_struct args;
args.arg1 = 5;
args.arg2 = 7;
if (pthread_create(&some_thread, NULL, &print_the_arguments, (void *)&args) != 0) {
printf("Uh-oh!\n");
return -1;
}
return pthread_join(some_thread, NULL); /* Wait until thread is finished */
}
Результат для этого должен быть:
5
7
Но когда я запускаю его, я получаю:
141921115
-1947974263
Кто-нибудь знает, что я делаю не так?
Ответы:
Потому что ты сказал
struct arg_struct *args = (struct arg_struct *)args;
вместо того
struct arg_struct *args = arguments;
источник
использовать
struct arg_struct *args = (struct arg_struct *)arguments;
на месте
struct arg_struct *args = (struct arg_struct *)args;
источник
main()
имеет собственные переменные потока и стека. либо выделите память для аргументов в куче, либо сделайте ее глобальной:struct arg_struct { int arg1; int arg2; }args; //declares args as global out of main()
Затем, конечно, измените ссылки с
args->arg1
на иargs.arg1
т. Д.источник
Использование:
struct arg_struct *args = malloc(sizeof(struct arg_struct));
И передайте эти аргументы следующим образом:
pthread_create(&tr, NULL, print_the_arguments, (void *)args);
Не забывайте бесплатные аргументы! ;)
источник
Аргументы print_the_arguments - это аргументы, поэтому вы должны использовать:
struct arg_struct *args = (struct arg_struct *)arguments.
источник
struct arg_struct *args = (struct arg_struct *)args;
-> это назначение неверно, я имею в виду, что в этом контексте следует использовать аргумент переменной. Ура !!!
источник
При создании потока этого кода передается адрес указателя функции. Оригинал
pthread_create(&some_thread, NULL, &print_the_arguments, (void *)&args) != 0
Его следует читать как
pthread_create(&some_thread, NULL, print_the_arguments, (void *) &args)
Хороший способ запомнить - все аргументы этой функции должны быть адресами.
some_thread
объявляется статически, поэтому адрес отправляется правильно с использованием&
.Я бы создал
pthread_attr_t
переменную, затем использовал быpthread_attr_init()
ее и передал адрес этой переменной. Но передачаNULL
указателя также допустима.То,
&
что вызывает проблему, - это перед меткой функции. Используемая метка уже являетсяvoid*
функцией, поэтому необходима только метка.Сказать
!= 0
последний аргумент, по-видимому, приведет к неопределенному поведению. Добавление этого означает, что вместо ссылки передается логическое значение.Ответ Акаша Агравала также является частью решения проблемы этого кода.
источник
У меня тот же вопрос, что и у оригинального постера, Майкл.
Однако я безуспешно пытался применить ответы, представленные для исходного кода.
После некоторых проб и ошибок вот моя версия кода, которая работает (или, по крайней мере, работает для меня!). И если вы присмотритесь, вы заметите, что это отличается от ранее опубликованных решений.
#include <stdio.h> #include <stdlib.h> #include <pthread.h> struct arg_struct { int arg1; int arg2; } *args; void *print_the_arguments(void *arguments) { struct arg_struct *args = arguments; printf("Thread\n"); printf("%d\n", args->arg1); printf("%d\n", args->arg2); pthread_exit(NULL); return NULL; } int main() { pthread_t some_thread; args = malloc(sizeof(struct arg_struct) * 1); args->arg1 = 5; args->arg2 = 7; printf("Before\n"); printf("%d\n", args->arg1); printf("%d\n", args->arg2); printf("\n"); if (pthread_create(&some_thread, NULL, &print_the_arguments, args) != 0) { printf("Uh-oh!\n"); return -1; } return pthread_join(some_thread, NULL); /* Wait until thread is finished */ }
источник