![](/img/trans.png)
[英]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.