как передать сетку в "void my_func (void * args)" - PullRequest
2 голосов
/ 29 апреля 2019

Я использую pthread_create() для вызова функции, строка заголовка которой void * my_func(void *args).Эта функция настраивает все необходимые ей аргументы из структуры данных.

Однако my_func() также необходим доступ к сетке, которая создается в другом месте.

Я попытался передать сетку каквходной аргумент рядом с void *args, однако это приводит к ошибкам, выдаваемым функцией pthread_create(), поскольку это не позволяет / не ожидает этого.

Вместо этого я попытался добавить сетку в структуру (не уверен, что это законный ход), однако это привело к тому, что сетка 'необъявлена' в пределах my_func() независимо.

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

1 Ответ

0 голосов
/ 29 апреля 2019

Создайте файл заголовка (назовите его thread_func.h или как вам удобнее)

#ifndef THREAD_FUNC_H
#define THREAD_FUNC_H
void* my_func(void *args);
#endif

Сделайте то же самое для вашей структуры thread_data_s, но в другом файле заголовка и включите определениедля него также.

Создайте файл .c с именем thread_func.c и поместите туда определение my_func(struct thread_data_s *data).Убедитесь, что #include заголовок, в котором вы определили свою структуру, но НЕ #include "thread_func.h", за исключением вашего main.c.Я также настоятельно рекомендую вам не использовать ваши указатели.

Если вы хотите увидеть пример макета, который я описал, у меня есть один на моем GitHub .

Редактировать:
Что касается передачи сетки в my_func, просто сделайте ее частью thread_data_s.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...