あなたはPythonと同じことを行います。複数のオブジェクトでできた複合オブジェクトの引数を渡します。 Cが低レベルの言語なので、あなたは手動でいくつかのことを管理する必要があります。複合オブジェクトの型を宣言する必要があります。型を一貫して使用し、複合オブジェクトのメモリを管理する必要があります。したがって、Pythonの場合と同じ概念的なコアですが、実際にはかなり困難です。
Cにはスタティック型があり、その型システムには構造集約型がないため、渡すデータの型を宣言する必要があります。整数と文字を渡したいとします。
typedef struct {
int y;
char *z;
} thread_param_t;
スレッド作成関数を呼び出すときは、この型のオブジェクトを作成し、それにポインタを渡す必要があります。
thread_param_t param = {42, "hello"};
pthread_create(thread, attr, entry_point, ¶m);
…
pthread_join(thread, NULL);
スレッドのコードを実行する関数は、タイプvoid*
の引数をとります。 void*
とはなんですか?これはCで多態性を行う方法です。void
へのポインタは、それが何を指しているのかを知らないポインタです。それを渡す以外には直接使用することはできませんが、どの型へのポインタもvoidへのポインタに変換することができます。たとえば、pthread_create
の4番目の引数の型はvoid*
であり、上記のパラメータの型はthread_param_t*
です。
void* entry_point(void *param_arg) {
thread_param_t *param = param_arg;
printf("entry_point called with y=%d and z=%s\n", param->y, param->z);
…
}
Cは実行時に型情報を持ちません。ポインタをvoid*
に変換して元のタイプに戻しても問題ありません。ポインタをvoid*
に変換してから別のタイプへのポインタに変換するのは問題ではありませんが、誤ってこれを行うと良い例外は得られません。運が良ければ、クラッシュします破損していない場合は、デバッグするのが難しい動作になります。
さらに、パラメータオブジェクトで使用されるメモリを管理する必要があります。上記では、パラメータオブジェクトをローカル変数として宣言する方法を示しました。これを関数に入れると、オブジェクトは関数が返るまで存在します。 (ブロック内でparam
が宣言されている場合は、ブロックの閉じブレースまで有効です)関数がパラメータオブジェクトへのアクセスを終了するのを待っていれば問題ありません。しかし、それは十分ではないので、メモリを動的に割り当てる必要があります。
thread_param_t *param;
param = malloc(sizeof(*param));
if (param == NULL) …;
pthread_create(thread, attr, entry_point, ¶m);
オブジェクトが動的に割り当てられているので、あなたはそれがオブジェクトの使用を終了しています後、おそらくentry_point
に、いくつかの点で、それにfree
を呼び出す必要があります。
は、あなたが探している構造体の 'struct'ですか? –
ああ、私はそれを考えなかった! –