Muszę przekazać wiele argumentów do funkcji, którą chciałbym wywołać w osobnym wątku. Mam przeczytać , że typowy sposób, aby to zrobić, aby zdefiniować struct, zdać funkcję wskaźnika do tego, i wyłuskanie go do argumentów. Jednak nie mogę sprawić, żeby to zadziałało:
#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 */
}
Wynik tego powinien być:
5
7
Ale kiedy go uruchamiam, faktycznie otrzymuję:
141921115
-1947974263
Czy ktoś wie, co robię źle?
Odpowiedzi:
Ponieważ mówisz
struct arg_struct *args = (struct arg_struct *)args;
zamiast
struct arg_struct *args = arguments;
źródło
posługiwać się
struct arg_struct *args = (struct arg_struct *)arguments;
zamiast
struct arg_struct *args = (struct arg_struct *)args;
źródło
main()
ma swój własny wątek i zmienne stosu. albo przydziel pamięć dla „args” w stercie, albo uczyń ją globalną:struct arg_struct { int arg1; int arg2; }args; //declares args as global out of main()
Następnie oczywiście zmień odniesienia z
args->arg1
naargs.arg1
itd.źródło
Posługiwać się:
struct arg_struct *args = malloc(sizeof(struct arg_struct));
I przekaż te argumenty w ten sposób:
pthread_create(&tr, NULL, print_the_arguments, (void *)args);
Nie zapomnij o darmowych argumentach! ;)
źródło
Argumenty funkcji print_the_arguments to argumenty, więc powinieneś użyć:
struct arg_struct *args = (struct arg_struct *)arguments.
źródło
struct arg_struct *args = (struct arg_struct *)args;
-> to przypisanie jest błędne, mam na myśli argument zmiennej powinien być używany w tym kontekście. Twoje zdrowie!!!
źródło
Podczas tworzenia wątku tego kodu przekazywany jest adres wskaźnika funkcji. Oryginalny
pthread_create(&some_thread, NULL, &print_the_arguments, (void *)&args) != 0
Powinien brzmieć jako
pthread_create(&some_thread, NULL, print_the_arguments, (void *) &args)
Dobrym sposobem na zapamiętanie jest to, że wszystkie argumenty tej funkcji powinny być adresami.
some_thread
jest deklarowana statycznie, więc adres jest wysyłany poprawnie za pomocą&
.Utworzyłbym
pthread_attr_t
zmienną, następnie użyłbympthread_attr_init()
jej i przekazał adres tej zmiennej. Ale przekazanieNULL
wskaźnika jest również prawidłowe.Przyczyną
&
problemu jest tutaj przed etykietą funkcji. Użyta etykieta jest już przypisanavoid*
do funkcji, więc wymagana jest tylko etykieta.Powiedzenie
!= 0
za pomocą ostatniego argumentu wydaje się powodować nieokreślone zachowanie. Dodanie tego oznacza, że zamiast referencji przekazywana jest wartość logiczna.Odpowiedź Akasha Agrawala jest również częścią rozwiązania problemu tego kodu.
źródło
Mam to samo pytanie, co przy oryginalnym plakacie, Michael.
Jednak bez powodzenia próbowałem zastosować przesłane odpowiedzi do oryginalnego kodu
Po kilku próbach i błędach, oto moja wersja kodu, która działa (lub przynajmniej działa dla mnie!). A jeśli przyjrzysz się uważnie, zauważysz, że różni się on od wcześniej opublikowanych rozwiązań.
#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 */ }
źródło