2012-04-29 38 views
1

当我们使用pthread_create创建线程时,我们应该将pthread_join立即放置吗?使用pthread_join时出现混乱(线程,NULL)

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

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

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

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

+0

你错过了最好的选择 - 不使用join()方法在所有。 – 2012-04-29 11:14:44

回答

5

第一个版本启动九个线程。
然后一旦所有的线程都被创建完毕,它将等待它们全部完成后退出。
因此,您可以获得9个并行运行的线程。

第二个版本启动九个线程。
但是在每个线程启动之后,它会等待线程退出,然后再继续。
因此,您可以获得连续运行的九个线程。

不幸的是,第一个版本也被打破。
传递给线程的数据对象(作为第四个参数(&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]); 

    } 
+0

谢谢,这对我很有帮助,说明很清楚。 – mitweyl 2012-04-29 10:30:21

0

您的所有线程与它们的参数共享相同的内存区域,因为您反复将指针传递给同一个栈分配变量M。在工作线程正在运行时,您在主循环中更改M,从而导致不确定的结果。在第二个版本中,您基本上已将代码转换为顺序,因为pthread_join在您开始下一步之前等待每个线程终止,这就是为什么它能正常工作。