Tparam
がどのように宣言されたかを示していただきありがとうございます。
しかし、各スレッドにいくつかのデータを格納するための独自の領域を持たせたい場合は、関数の引数としてその領域をスレッドに渡すことができます。たとえば、
enum { NTHREADS = 10 };
struct TLS_Data
{
int id;
char buffer[2048];
size_t index;
} data[NTHREADS];
for (int c1 = 0; c < NTHREADS; c1++)
{
data[c1].index = c1;
data[c1].id = 0;
data[c1].buffer[0] = '\0';
int rc = pthread_create(&threads[c1], NULL, Thread_Pool, &data[c1]);
...handle errors, etc...
}
pthread_create()
の最後の引数にキャストがないことに注意してください。スコープ内にプロトタイプがある場合、ポインタをvoid *
に変換する必要はありません。
Thread_Pool
には、パラメータを整数として扱いたいようです。それも実行することができます。整数へのポインタを渡すことで、きれいに完了します。あなたが本当に主張する場合は、直接整数値を渡すことができますvalue
のタイプはuintptr_t
ある
uintptr_t value = c1 + 10;
rc = pthread_create(&threads[c1], NULL, Thread_Pool, (void *)value);
ので、あなたはそれがボイドポインタを保持することが可能である知っている、そしてそれはあなたの作業物事の最大の機会を与えてくれます。しかし、タイプシステムと戦っているので、クリーンなコードを書くのが難しくなります。
注意すべき点の1つは、スレッド関数(例ではThread_Pool()
)に渡されたデータが、異なる値を参照すると見なされるスレッド間で共有されないようにする必要があることです。スレッドの実行順序の保証はありませんので、あなたのようなミスを犯した場合:
uintptr_t value = c1 + 10;
rc = pthread_create(&threads[c1], NULL, Thread_Pool, &value);
(およびそのコードがループしていた)、その後、どのような各スレッド機能については保証されるものではないと思いますでしょう見る。慎重にしてください!
pthread_keycreateなど。 – bmargulies
__thread接頭辞を使用して、単にスレッドローカル変数を使用するのはなぜですか?たとえば__thread int tl_var;第2に、書き込み禁止になっている位置0を指しているので、ヌルポインタに書き込むことはできません!あなたがこれをしようとすると、セグメンテーション違反が発生します。 – MetallicPriest
@bmargulies私はpthread_keycreateを読んで、これがうまくいくかどうか疑問に思いました。 – CodeRed