0

構造体をパラメーターとして pthread_create に渡そうとしていますが、奇妙な結果が得られているようです。

構造体には 2 つのメンバーがあり、最初のメンバーは int で、2 番目のメンバーは関数ポインターです。

typedef struct
{
  int num;
  void (*func)(int);
} foo_t;

構造体内で使用しようとしている関数:

void myfunc(int mynum)
{
   printf("mynum: %d\n", mynum);
}

これは、スレッドに渡す構造体の宣言です。

foo_t f;
f.num = 42;
f.func = &myfunc;

pthread_create の呼び出し:

pthread_create(&mythread, NULL, mythreadfunc, &f);

そして最後に、私のスレッド関数:

void mythreadfunc(void *foo)
{
   foo_t f = *(foo_t *)foo;
   printf("num: %d\n", f.num); // Prints: num: 32776 (undefined?)
   (*f.func)(f.num);  // Segfaults (again, undefined?)
...

mythreadfunc 内のキャストが機能していないようで、その理由がわかりません。助言がありますか?ありがとう。

4

2 に答える 2

1

あなたはfoo_t f参照によってあなたを渡しています。-calling 関数または他の場所fから変更している場合、たとえば、対応するスコープを離れるとスタックから削除/削除される場合、スレッド内の参照は (ほとんどの場合) 無効です。少なくとも、もうアクセスしないでください。pthread_createf

代わりに、動的に割り当てられた変数を持つポインターを使用してください。

あなたが提示したコードでこれが起こっていることを証明することはできませんが。

編集:

ポインターは、オブジェクト/変数のアドレスを格納するために使用されます。C/C++動的に割り当てられたメモリセグメントを指すようにすることができます。これを探してくださいmalloc/new。ポインターで呼び出されることを実行しdereferencing、オブジェクト/変数自体にアクセスできます。

値ごとにポインターを渡すことができます。つまり、オブジェクト/変数自体を渡すのではなく、RAM 内のオブジェクト/変数のアドレス (= 位置) を渡します。動的に割り当てられた変数/オブジェクトのメモリ管理はプログラマの責任であるため、ポインタのスコープが終了してもオブジェクトは削除されず、アドレスを格納するポインタのみが削除されます。

于 2012-08-20T12:03:03.220 に答える
1

Papergay の答えは間違いなく 1 つの解決策ですが、動的割り当てを回避したい場合に使用できる別のアプローチは、同期を使用することです。私のお気に入りのアプローチは、構造体に初期値ゼロのセマフォを配置し、親がセマフォで待機し、子が構造体から値を読み取った後にセマフォを送信することです。

于 2012-08-20T12:07:45.077 に答える