1

でスレッドを作成するとき、即時pthread_createを配置する必要がありますか?pthread_join

たとえば、次の 2 つのコードがありますが、なぜ機能しないのかわかりません。

最初のバージョンでは、出力は確定的ではありません。

#include<iostream>
#include<pthread.h>
#include<cstring>
#include<cstdlib>
#define ROW 3
#define COL 3
using namespace std;
typedef struct {
int row;
int col;
} para;
void print(double * para)
{
    for(int i=0;i<3;i++)
   {
           for(int j=0;j<3;j++)
           {
                    cout<<*(para+3*i+j)<<"\t";
            }
            cout<<endl;
        }

}
double mat[9]={1,2,3,4,5,6,7,8,9};
double * result=(double *) malloc(9*sizeof(double));
void * mul(void * arg)
{
        para * temp=(para *) arg;
        int row=temp->row;
        int col=temp->col;
        double sum=0;
        for(int i=0;i<3;i++)
        {
                double a=*(mat+row*3+i);
                double b=*(mat+i+3*col);
                sum+=a*b;
        }
        *(result+row*3+col)=sum;
int main()
{
        pthread_t thread[9];
        for(int i=0;i<9;i++)
        {
                   para M;
                M.row=i/3;
                M.col=i%3;
                pthread_create(&thread[i],NULL,mul,&M);

        }
        for(int i=0;i<9;i++)
        {
                 pthread_join(thread[i],NULL);            
        }

        print(result);
}

2番目のバージョンでは、出力は正しいです。

#include<iostream>
#include<pthread.h>
#include<cstring>
#include<cstdlib>
#define ROW 3
#define COL 3
using namespace std;
typedef struct {
int row;
int col;
} para;
void print(double * para)
{
    for(int i=0;i<3;i++)
   {
           for(int j=0;j<3;j++)
           {
                    cout<<*(para+3*i+j)<<"\t";
            }
            cout<<endl;
        }

}
double mat[9]={1,2,3,4,5,6,7,8,9};
double * result=(double *) malloc(9*sizeof(double));
void * mul(void * arg)
{
        para * temp=(para *) arg;
        int row=temp->row;
        int col=temp->col;
        double sum=0;
        for(int i=0;i<3;i++)
        {
                double a=*(mat+row*3+i);
                double b=*(mat+i+3*col);
                sum+=a*b;
        }
        *(result+row*3+col)=sum;
int main()
{
        pthread_t thread[9];
        for(int i=0;i<9;i++)
        {
                   para M;
                M.row=i/3;
                M.col=i%3;
                pthread_create(&thread[i],NULL,mul,&M);
                pthread_join(thread[i],NULL); 
        }   
        print(result);
}

これら2つの使用法の違いは何ですか? そして、最初のコードに何か問題があるのはなぜですか?

4

2 に答える 2

5

最初のバージョンは 9 つのスレッドを開始します。
次に、すべてのスレッドが作成されると、終了する前にすべてのスレッドが終了するのを待ちます。
したがって、9 つのスレッドが並行して実行されます。

2 番目のバージョンは、9 つ​​のスレッドを開始します。
ただし、各スレッドが開始されると、スレッドが終了するのを待ってから続行します。
したがって、9 つのスレッドが連続して実行されます。

残念ながら、最初のバージョンも壊れています。
スレッドに (4 番目のパラメーター ( &M) として) 渡されるデータ オブジェクトは、スレッドが完了する前にスコープ外になる可能性のある自動変数です。

次のように修正します。

    pthread_t thread[9];
    para      M[9];
    for(int i=0;i<9;i++)
    {
            M[i].row = i/3;
            M[i].col = i%3;
            pthread_create(&thread[i],NULL,mul,&M[i]);

    }
于 2012-04-29T09:27:16.473 に答える
0

ポインタを同じスタック割り当て変数に繰り返し渡すため、すべてのスレッドはパラメータと同じメモリ領域を共有しますM。ワーカースレッドの実行中にメインループを変更Mすると、非決定論的な結果になります。pthread_join2番目のバージョンでは、次のスレッドを開始する前にすべてのスレッドが終了するのを待つため、基本的にコードをシーケンシャルに変換しました。これが、正しく機能する理由です。

于 2012-04-29T08:54:19.213 に答える