0

問題を説明するのは難しいと思うので、コードを投稿して何が起こるかを説明し、それから私が望むようにする方法を尋ねます。まず、子プロセス内にスレッドを作成します。

pid_t childpid = fork();

if(childpid == -1){
  cout << "Failed to fork." << endl;   
}
else if(childpid == 0){     
  //request threads
  pthread_t p1, p2, p3;          

  struct arg_struct args1, args2, args3;

  args1.name = "data Joe Smith";
  args1.num_req = n;
  args1.buff_size = b;
  pthread_create(&p1, NULL, &mythreadfunc, (void *)&args1);   
}

これは次のstruct arg_structとおりです。

struct arg_struct{
    string name;
    int num_req;
    int curr_value;
    int buff_size;
};

そしてそのmythreadfunc:

void *mythreadfunc(void *arguments){ 
    struct arg_struct *args = (struct arg_struct *)arguments;
    string local_name = args->name;     
    int local_num_req = args->num_req;
    //request new thread
    RequestChannel chan("control", RequestChannel::CLIENT_SIDE);
    cout << "done." << endl;
    string reply1 = chan.send_request("newthread");

    cout << "Reply to request 'newthread' is " << reply1 << "'" << endl;

    RequestChannel chan2(reply1, RequestChannel::CLIENT_SIDE); 

    cout<<"local_name:  "<<local_name<<endl;    //returns incorrect value***
    cout<<"local_num_req:  "<<local_num_req<<endl;  //returns incorrect value***

    //close up all channels
    string reply2 = chan2.send_request("quit");
    cout << "Reply to request 'quit' is '" << reply2 << "'" << endl;
    string reply3 = chan.send_request("quit");
    cout << "Reply to request 'quit is '"<< reply3 << "'" << endl;
}

local_nameとを使用する 2 つの回線local_num_reqには、問題があります。私は問題なくコンパイルしますが、2 つの変数は毎回異なるものを格納しているようです。適切に動作することもありますが、ガベージ値を保持していて、プログラムがそれら (またはそれに続くもの) を実行しないこともあります。args->nameローカル変数なしで元の名前 (つまり ) を使用しようとしましたが、問題は同じです。私の最善の推測はargs_struct、変数の処理が間違っているということですが、なぜ一部の時間だけ失敗するのかわかりません。

で正しい変数値を取得するにはどうすればよいmythreadfuncですか?

4

2 に答える 2

8

ヒープに新しいスレッドの引数を作成します。呼び出し元の関数の範囲外になるため、スレッドでの使用には有効ではありません。

struct arg_struct *arg1 = new arg_struct;

args1->num_req = n;
// etc...

pthread_create(&p1, NULL, &mythreadfunc, (void *) args1);
于 2012-07-28T21:42:05.893 に答える
1

p1どちらも新しいスレッドが作成されるとargs1すぐに範囲外になるため、実行中は存在しなくなりますmythreadfunc

コードを修正するには、それらのオブジェクトの有効期間を、それらを使用する新しいスレッドの有効期間よりも長くする必要があります。これは、ヒープ上にオブジェクトを作成するか、新しいスレッドが終了するまでオブジェクトがスコープ外に出ないようにする囲みスコープ内にオブジェクトを作成することで実行できます。

pthread_t p1, p2, p3;
struct arg_struct args1, args2, args3;

pid_t childpid = fork();

if(childpid == -1){
  cout << "Failed to fork." << endl;   
}
else if(childpid == 0){     
  //request threads

  args1.name = "data Joe Smith";
  args1.num_req = n;
  args1.buff_size = b;
  pthread_create(&p1, NULL, &mythreadfunc, (void *)&args1);   
}

// ...

void* res = pthread_join(&p1);

// safe for `args1` to go out of scope now
于 2012-07-28T21:59:09.260 に答える