3

各スレッドにスレッド固有のデータを提供しようとしています。これはスレッドパラメータを使用して実行できますか?

したがって、スレッドを作成するときに変数を渡し、スレッド関数でその値を変更して、各スレッドの特定のデータとして使用しますか?

int main(void){
    ...
    int Tparam = 0;
    ...
    rc = pthread_create(&threads[c1], NULL, Thread_Pool, (void *)Tparam);
    ...
}

次に、Thread_Pool関数で次のように使用します

void *Thread_Pool(void *param){
    int id;
    id = (int) param;
    id = value; // can this value be a specific value for this thread?
}
4

4 に答える 4

4

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では、パラメータを整数として扱いたいようです。それもできます。整数へのポインタを渡すのが最もきれいに行われます。本当に主張する場合は、整数値を直接渡すことができます。

uintptr_t value = c1 + 10;

rc = pthread_create(&threads[c1], NULL, Thread_Pool, (void *)value);

のタイプはであるためvalueuintptr_tvoidポインターを保持できることがわかります。したがって、これにより、動作する可能性が最大になります。しかし、あなたは型システムと戦っているので、クリーンなコードを書くのが難しくなります。

注意すべきことの1つは、スレッド関数に渡されたデータ(このThread_Pool()例では)が異なる値を参照することになっている場合は、スレッド間で共有されないようにする必要があるということです。スレッドの実行順序は保証されていないため、次のような間違いをした場合は次のようになります。

uintptr_t value = c1 + 10;

rc = pthread_create(&threads[c1], NULL, Thread_Pool, &value);

(そしてそのコードはループに入っていました)、その場合、各スレッド関数が何を見るかについての保証はありません。注意してください!

于 2012-05-05T20:14:44.257 に答える
2

この値をこのスレッドの特定の値にすることはできますか?

さて、まず最初に、あなたはおそらくこれが欲しいでしょう:

int id = *((int*) param);

つまり、型を持つポインターを指定した、パラメーターポインターを逆参照する必要があります。voidには型がないため、voidポインタを逆参照することはできません。

さて、ここで何が起こりますか?まず、スレッドを少し理解する必要があります。

まず、Linuxのカーネルではスレッドとプロセスの区別はありません。絶対にありません。それらはすべて実行またはタスクのコンテキストです。ただし、大きな違いの1つは、スレッドスタックを除いて、スレッド化されたタスクがデータを共有することです。その答えを読むと、スレッドが他のほとんどすべてをその作成者と共有していることがわかります。

ただし、スタックは共有しないでください。スタックは多くのことを追跡します。たとえば、プログラムが実行に関しては、一部のシステムでは値と関数パラメーターを返します。関数内で宣言された自動保存期間変数(他の修飾子がない変数)もスタックに保存されます。

つまり、スレッド関数内で宣言された変数は、そのスレッドに固有です。だから、あなたの機能を考えると:

void threadfunc(void* param)
{
    int id = /* ??? */
}

各スレッドには、ローカルに保存された独自のコピーがint idあり、スレッドの期間中持続します。これを値またはポインタで後続の関数に渡すことができます。

そのため、次のように呼び出すことは完全に有効です。

int tParam[] = {1,2,3};

rc = pthread_create(&threads[1], NULL, Thread_Pool, (void *)&(tParam[1]));
rc = pthread_create(&threads[2], NULL, Thread_Pool, (void *)&(tParam[2]));
rc = pthread_create(&threads[3], NULL, Thread_Pool, (void *)&(tParam[3]));

等々。

于 2012-05-05T20:12:20.897 に答える
1

pthread_self()を呼び出すことができます。一意のスレッドIDを返します。juampaが推奨したLLNLURLのAPIリファレンスを参照してください。

于 2012-05-05T20:09:39.947 に答える
-2

あなたの質問が分かりません; 私はまだあなたが本当に何をしたいのか理解できません。

いずれにせよ、サイトを確認することを強くお勧めします。

それらは短いですが、それでもあなたが始めるためにおそらく必要となるであろうもののほとんどを含んでいます。

于 2012-05-05T20:03:52.123 に答える