[英]Pthreads, confusion with pthread_join(pthread_t, void**)
[英]confusion in using of pthread_join ( thread, NULL)
当我们使用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);
}
这两种用法有什么区别? 为什么第一个代码有问题?
第一个版本启动九个线程。
然后,一旦创建了所有线程,它将等待所有线程完成后再退出。
因此,您获得了九个并行运行的线程。
第二个版本启动九个线程。
但是,在启动每个线程之后,它将等待线程退出,然后再继续。
因此,您获得了九个串行运行的线程。
不幸的是,第一个版本也被破坏了。
传递给线程的数据对象(作为第四个参数( &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]);
}
您的所有线程都与其参数共享相同的内存区域,因为您反复将指针传递给相同的堆栈分配变量M
当工作线程正在运行时,您可以在主循环中更改M
,从而导致不确定的结果。 在第二版中,您实际上已将代码转换为顺序代码,因为pthread_join
在下一个启动之前等待每个线程终止,这就是为什么它可以正常工作的原因。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.