如何将网格传递给 "void my_func(void *args)"
how to pass grid to "void my_func(void *args)"
我正在使用 pthread_create()
调用 header 行为 void * my_func(void *args)
的函数。此函数从数据结构中转换它需要的所有参数。
但是,my_func()
还需要访问在别处创建的网格。
我试过将网格作为输入参数与 void *args
一起传递,但是这会导致函数 pthread_create()
抛出错误,因为它不会 allow/expect 这个。
我尝试将网格添加到结构中(不确定这是否合法),但这导致网格在 my_func()
内 'undeclared' 无论如何。
pthreads_create()
代码:
for (k = 0; k < num_threads; k++)
pthread_create (&thread_id[k], &attributes, my_func, (void *) &thread_data[k]);
my_func()
代码:
/* This function is executed by each thread to compute the overall Gauss-Seidel. */
void *
my_func (void *args)
{
/* Typecast the argument to a pointer to the thread_data_t structure. */
thread_data_t *thread_data = (thread_data_t *) args;
// int num_iter = 0;
int done = 0;
int i, j;
double diff;
float old, new;
float eps = 1e-2; /* Convergence criteria. */
int num_elements;
int num_iter = 0;
if (thread_data->tid < (thread_data->num_threads - 1)) {
for (int k = thread_data->offset; k < (thread_data->offset + thread_data->chunk_size); k++)
while(!done) { /* While we have not converged yet. */
diff = 0.0;
num_elements = 0;
for (i = 1; i < (grid->dim - 1); i++) {
for (j = 1; j < (grid->dim - 1); j++) {
old = grid->element[i * grid->dim + j]; /* Store old value of grid point. */
/* Apply the update rule. */
new = 0.25 * (grid->element[(i - 1) * grid->dim + j] +\
grid->element[(i + 1) * grid->dim + j] +\
grid->element[i * grid->dim + (j + 1)] +\
grid->element[i * grid->dim + (j - 1)]);
grid->element[i * grid->dim + j] = new; /* Update the grid-point value. */
diff = diff + fabs(new - old); /* Calculate the difference in values. */
num_elements++;
}
}
/* End of an iteration. Check for convergence. */
diff = diff/num_elements;
printf ("Iteration %d. DIFF: %f.\n", num_iter, diff);
num_iter++;
if (diff < eps)
done = 1;
} // end while
} //end if
else { /* This takes care of the number of elements that the final thread must process. */
int done2 = 0;
for (int k = thread_data->offset; k < thread_data->dim; k++)
while(!done2) { /* While we have not converged yet. */
diff = 0.0;
num_elements = 0;
for (i = 1; i < (grid->dim - 1); i++) {
for (j = 1; j < (grid->dim - 1); j++) {
old = grid->element[i * grid->dim + j]; /* Store old value of grid point. */
/* Apply the update rule. */
new = 0.25 * (grid->element[(i - 1) * grid->dim + j] +\
grid->element[(i + 1) * grid->dim + j] +\
grid->element[i * grid->dim + (j + 1)] +\
grid->element[i * grid->dim + (j - 1)]);
grid->element[i * grid->dim + j] = new; /* Update the grid-point value. */
diff = diff + fabs(new - old); /* Calculate the difference in values. */
num_elements++;
}
}
/* End of an iteration. Check for convergence. */
diff = diff/num_elements;
printf ("Iteration %d. DIFF: %f.\n", num_iter, diff);
num_iter++;
if (diff < eps)
done = 1;
} // end while
}// end else
/* Store num_iter into the num_iter array. */
thread_data->num_iter[thread_data->tid] = num_iter;
pthread_exit (NULL);
}
创建一个 header 文件(将其命名为 thread_func.h
或您喜欢的任何名称)
#ifndef THREAD_FUNC_H
#define THREAD_FUNC_H
void* my_func(void *args);
#endif
对您的 thread_data_s
结构执行相同的操作,但在不同的 header 文件中,并包含它的定义。
创建一个名为 thread_func.c
的 .c
文件,并将 my_func(struct thread_data_s *data)
的定义放在那里。确保 #include
定义结构的 header,但不要 #include "thread_func.h"
除了 main.c
。我也强烈建议你不要投你的指针。
如果您想查看我所描述的布局示例,我有一个 on my GitHub。
编辑:
至于将网格传递给my_func
,只需将其作为thread_data_s
的一部分即可。
我正在使用 pthread_create()
调用 header 行为 void * my_func(void *args)
的函数。此函数从数据结构中转换它需要的所有参数。
但是,my_func()
还需要访问在别处创建的网格。
我试过将网格作为输入参数与 void *args
一起传递,但是这会导致函数 pthread_create()
抛出错误,因为它不会 allow/expect 这个。
我尝试将网格添加到结构中(不确定这是否合法),但这导致网格在 my_func()
内 'undeclared' 无论如何。
pthreads_create()
代码:
for (k = 0; k < num_threads; k++)
pthread_create (&thread_id[k], &attributes, my_func, (void *) &thread_data[k]);
my_func()
代码:
/* This function is executed by each thread to compute the overall Gauss-Seidel. */
void *
my_func (void *args)
{
/* Typecast the argument to a pointer to the thread_data_t structure. */
thread_data_t *thread_data = (thread_data_t *) args;
// int num_iter = 0;
int done = 0;
int i, j;
double diff;
float old, new;
float eps = 1e-2; /* Convergence criteria. */
int num_elements;
int num_iter = 0;
if (thread_data->tid < (thread_data->num_threads - 1)) {
for (int k = thread_data->offset; k < (thread_data->offset + thread_data->chunk_size); k++)
while(!done) { /* While we have not converged yet. */
diff = 0.0;
num_elements = 0;
for (i = 1; i < (grid->dim - 1); i++) {
for (j = 1; j < (grid->dim - 1); j++) {
old = grid->element[i * grid->dim + j]; /* Store old value of grid point. */
/* Apply the update rule. */
new = 0.25 * (grid->element[(i - 1) * grid->dim + j] +\
grid->element[(i + 1) * grid->dim + j] +\
grid->element[i * grid->dim + (j + 1)] +\
grid->element[i * grid->dim + (j - 1)]);
grid->element[i * grid->dim + j] = new; /* Update the grid-point value. */
diff = diff + fabs(new - old); /* Calculate the difference in values. */
num_elements++;
}
}
/* End of an iteration. Check for convergence. */
diff = diff/num_elements;
printf ("Iteration %d. DIFF: %f.\n", num_iter, diff);
num_iter++;
if (diff < eps)
done = 1;
} // end while
} //end if
else { /* This takes care of the number of elements that the final thread must process. */
int done2 = 0;
for (int k = thread_data->offset; k < thread_data->dim; k++)
while(!done2) { /* While we have not converged yet. */
diff = 0.0;
num_elements = 0;
for (i = 1; i < (grid->dim - 1); i++) {
for (j = 1; j < (grid->dim - 1); j++) {
old = grid->element[i * grid->dim + j]; /* Store old value of grid point. */
/* Apply the update rule. */
new = 0.25 * (grid->element[(i - 1) * grid->dim + j] +\
grid->element[(i + 1) * grid->dim + j] +\
grid->element[i * grid->dim + (j + 1)] +\
grid->element[i * grid->dim + (j - 1)]);
grid->element[i * grid->dim + j] = new; /* Update the grid-point value. */
diff = diff + fabs(new - old); /* Calculate the difference in values. */
num_elements++;
}
}
/* End of an iteration. Check for convergence. */
diff = diff/num_elements;
printf ("Iteration %d. DIFF: %f.\n", num_iter, diff);
num_iter++;
if (diff < eps)
done = 1;
} // end while
}// end else
/* Store num_iter into the num_iter array. */
thread_data->num_iter[thread_data->tid] = num_iter;
pthread_exit (NULL);
}
创建一个 header 文件(将其命名为 thread_func.h
或您喜欢的任何名称)
#ifndef THREAD_FUNC_H
#define THREAD_FUNC_H
void* my_func(void *args);
#endif
对您的 thread_data_s
结构执行相同的操作,但在不同的 header 文件中,并包含它的定义。
创建一个名为 thread_func.c
的 .c
文件,并将 my_func(struct thread_data_s *data)
的定义放在那里。确保 #include
定义结构的 header,但不要 #include "thread_func.h"
除了 main.c
。我也强烈建议你不要投你的指针。
如果您想查看我所描述的布局示例,我有一个 on my GitHub。
编辑:
至于将网格传递给my_func
,只需将其作为thread_data_s
的一部分即可。