c-使用条件变量在多线程中冻结



使用伪代码,我必须实现它,以便并行化计算成本高昂的程序(热分布问题的Jacobi迭代方法(。

主线程的伪代码:

Create N workers; each with a set of rows
While not max time step or threshold is reached 
wait for all workers to finish their computation 
check the max temp diff returned by all workers 
swap matrices u and w
if overall max temp diff > ε
wake up all workers to execute next time step
else threshold has reached
wake up all workers and inform them to terminate
endif
Wait for all workers and print their running statistics 
Get and print master running statistics
Update final_diff
Return no. of temp steps

工作线程的伪代码

Identify which set of rows to compute
While not terminate yet
Compute the temp of all points in its set 
Find the max temp diff in this set
Signal master to test the diff 
Wait for master instruction
if instruction == stop 
break the while loop
else instruction == continue 
continue the while loop
endif
Get its running statistics and pass it to master 
Terminate

我不知道为什么我的程序被冻结,可能是由于以下两个原因:

  1. 在主线程中;等待所有工人完成他们的计算">
  2. 在worker线程中;信号主线程测试差异">

我的代码如下:

主线程

int find_steady_state (void)
{
// (3) Implement the thread creation and the main control logic here
int thread_rtn;
int * rptr;
pthread_mutex_init(&mlock, NULL);
pthread_mutex_init(&nlock, NULL);
pthread_cond_init(&cond, NULL);
pthread_cond_init(&mum, NULL);
pthread_t thr_kids[thr_count];
int i_value[thr_count];
int rtn;
double **temp;

//Create N thread, according to the input
for(int i = 0; i < thr_count; ++i){
i_value[i] = i;
thread_rtn = pthread_create(&thr_kids[i], NULL, &thr_func, (void*)&i_value[i]);
}

//run from 1 to max time step
for(int its = 1; its < max_its; ++its){
printf("Trial%d, count is %dn", its, count);
//find the maximum element in array sum_temp
//sum_temp stored all the max temp in correspond location, eg: sum_temp[0] = max temp of first thread.
max_temp = fmax(sum_temp[count], sum_temp[count-1]);
//Wait for all workers to finish their work
pthread_mutex_lock(&mlock);
while(count != 0){
pthread_cond_wait(&mum, &mlock);
}
pthread_mutex_lock(&mlock);
printf("--- Main thread Wake up!! ---n");
//swap the matrix
temp = u;
u = w;
w = temp;
printf("--- Mother: The matrix is swapped ---n");
// test the value, if the value > EPSILON --> wake up all thread to execute next iterations.
// else, wake up all thread and tell them to terminate.
if(max_temp > EPSILON){
stop = false;
pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&nlock);
printf("--- Mother: need to continue with temp = %f --- n", max_temp);
count = thr_count;
}
else{
stop = true;
pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&nlock);
printf("--- Mother: Will Break with temp = %f --- n", max_temp);
break;
}
rtn = its;
}
/* Terminate the thread
Print the running statistic
*/
for(int i = 0; i < thr_count; ++i){
pthread_join(thr_kids[i], (void **) &rtnArray);
printf("Thread %d has completed - user: %.4f s, system: %.4f sn", i, rtnArray[0], rtnArray[1]);
// return iteration time
}
// update final_diff
final_diff = max_temp;
printf("--- Final temp: %f ---n", final_diff);
return rtn;
}

工人线程

void *thr_func(void *arg) {
// (2) Add the worker's logic here
int x = *((int*)arg);
//Split the computation evenly
int start = x*(N/thr_count)+1;
int end = (x+1)*N/thr_count;
double diff = 0.0;
count = thr_count;

// used to return user time and sys time.
struct rusage usage;
if (end == N)
{
end = end - 1;
}
//While not terminate
while(true){
//find the max temp  diff in the set
for(int i = start; i <end; i++){
for(int j = 1; j < N-1;j++){
w[i][j] = 0.25 * (u[i-1][j] + u[i+1][j] + u[i][j-1] + u[i][j+1]);
if(fabs(w[i][j] - u[i][j]) > diff)
diff = fabs(w[i][j] - u[i][j]);
}
}
if(diff >= sum_temp[x]){
sum_temp[x] = diff;
printf("new temp for trial %d = %fn", x, sum_temp[x]);
}
//Signal master thread to test the diff
count--;
if(count == 0){
pthread_cond_signal(&mum);
pthread_mutex_unlock(&mlock);
}
pthread_mutex_lock(&nlock);
/*Wait for the master instruction
if stop == true --> main thread tells workers can stop work
else stop == false --> run the loop again.
*/
pthread_cond_wait(&cond, &nlock);
//receive the instruction 
// stop is bool type 
if(stop){
printf("--- STOP!!! --- n");
break;
}
else if(!stop){
printf("--- Continue ---n");
continue;
}
}
printf("Count = %dn", count);
printf("nThread%d: The max temp diff for the set between %d and %d is: %fn", x,  start, end, diff);
/* terminate and return running statistic
send to main thread
*/
rtnArray = (float*) malloc(sizeof(float) *2);
rtnArray[0] = (usage.ru_utime.tv_sec + usage.ru_utime.tv_usec/1000000.0);
rtnArray[1] = (usage.ru_stime.tv_sec + usage.ru_stime.tv_usec/1000000.0);
pthread_exit(rtnArray);
return rtnArray;
}

Q: 在主线程中,如何"等待所有工人完成他们的计算">
A:pthread_barrier_wait(另请参阅pthread_barrier_init(

Q: 在worker线程中,如何"信号主线程测试差异">
A:无需信号。同样,如果主线程在屏障处等待,那么它将在所有线程都到达该屏障后继续。

您的代码只需要两个屏障,不需要互斥或条件变量。

相关内容

  • 没有找到相关文章

最新更新