1

当我们创建一个带有 的线程时pthread_create,我们应该放置pthread_join立即数吗?

例如我有以下两个代码,但我不知道为什么它不起作用。

对于第一个版本,输出不是确定性的。

#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);
}

使用第二个版本,输出是正确的。

#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);
}

这两种用法有什么区别?为什么第一个代码有问题?

4

2 回答 2

5

第一个版本启动九个线程。
然后,一旦创建了所有线程,它就会在退出之前等待它们全部完成。
因此,您将获得 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_join在您开始下一个之前等待每个线程终止,这就是它正常工作的原因。

于 2012-04-29T08:54:19.213 回答