Saya perlu meneruskan beberapa argumen ke fungsi yang ingin saya panggil di utas terpisah. Saya telah membaca bahwa cara khas untuk melakukan ini adalah dengan mendefinisikan sebuah struct, meneruskan fungsi sebuah pointer ke sana, dan membedakannya untuk argumen. Namun, saya tidak dapat membuat ini berfungsi:
#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 */
}
Output untuk ini seharusnya:
5
7
Tetapi ketika saya menjalankannya, saya benar-benar mendapatkan:
141921115
-1947974263
Ada yang tahu apa yang saya lakukan salah?
Jawaban:
Karena kamu bilang
struct arg_struct *args = (struct arg_struct *)args;
dari pada
struct arg_struct *args = arguments;
sumber
menggunakan
struct arg_struct *args = (struct arg_struct *)arguments;
di tempat
struct arg_struct *args = (struct arg_struct *)args;
sumber
main()
memiliki variabel utas dan tumpukannya sendiri. mengalokasikan memori untuk 'args' di heap atau menjadikannya global:struct arg_struct { int arg1; int arg2; }args; //declares args as global out of main()
Kemudian tentu saja mengubah referensi dari
args->arg1
keargs.arg1
dll ..sumber
Menggunakan:
struct arg_struct *args = malloc(sizeof(struct arg_struct));
Dan berikan argumen ini seperti ini:
pthread_create(&tr, NULL, print_the_arguments, (void *)args);
Jangan lupakan argumen gratis! ;)
sumber
Argumen print_the_arguments adalah argumen, jadi Anda harus menggunakan:
struct arg_struct *args = (struct arg_struct *)arguments.
sumber
struct arg_struct *args = (struct arg_struct *)args;
-> tugas ini salah, maksud saya argumen variabel harus digunakan dalam konteks ini. Bersulang!!!
sumber
Dalam pembuatan utas kode ini, alamat penunjuk fungsi sedang diteruskan. Asli
pthread_create(&some_thread, NULL, &print_the_arguments, (void *)&args) != 0
Ini harus dibaca sebagai
pthread_create(&some_thread, NULL, print_the_arguments, (void *) &args)
Cara yang baik untuk mengingat adalah bahwa semua argumen fungsi ini harus berupa alamat.
some_thread
dideklarasikan secara statis, sehingga alamat dikirim dengan benar menggunakan&
.Saya akan membuat
pthread_attr_t
variabel, lalu menggunakannyapthread_attr_init()
dan meneruskan alamat variabel itu. Tapi, melewatkanNULL
pointer juga valid.Bagian
&
depan label fungsi inilah yang menyebabkan masalah di sini. Label yang digunakan sudah menjadivoid*
suatu fungsi, jadi hanya label yang diperlukan.Mengatakan
!= 0
dengan argumen terakhir tampaknya akan menyebabkan perilaku yang tidak dapat ditentukan. Menambahkan ini berarti bahwa boolean sedang diteruskan, bukan referensi.Jawaban Akash Agrawal juga merupakan bagian dari solusi untuk masalah kode ini.
sumber
Saya memiliki pertanyaan yang sama dengan poster asli, Michael.
Namun saya telah mencoba menerapkan jawaban yang dikirimkan untuk kode asli tanpa hasil
Setelah beberapa kali coba-coba, berikut adalah versi kode saya yang berfungsi (atau setidaknya berfungsi untuk saya!). Dan jika Anda melihat lebih dekat, Anda akan melihat bahwa ini berbeda dengan solusi sebelumnya yang diposting.
#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 */ }
sumber