Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 当线程执行循环迭代时,如何继续使用master?_C_Multithreading_Performance_Parallel Processing_Openmp - Fatal编程技术网

C 当线程执行循环迭代时,如何继续使用master?

C 当线程执行循环迭代时,如何继续使用master?,c,multithreading,performance,parallel-processing,openmp,C,Multithreading,Performance,Parallel Processing,Openmp,我被要求用C编写一个OpenMP程序,这样主线程就可以将工作分配给其他线程,当它们执行任务时,主线程应该定期检查它们是否完成,如果没有完成,它应该增加一个共享变量 这是线程任务的函数: void work_together(int *a, int n, int number, int thread_count) { # pragma omp parallel for num_threads(thread_count) \ shared(a, n, number) privat

我被要求用C编写一个OpenMP程序,这样主线程就可以将工作分配给其他线程,当它们执行任务时,主线程应该定期检查它们是否完成,如果没有完成,它应该增加一个共享变量

这是线程任务的函数:

void work_together(int *a, int n, int number, int thread_count) {
#   pragma omp parallel for num_threads(thread_count) \
        shared(a, n, number) private(i) schedule(static, n/thread_count)
    for (long i=0; i<n; i++) {
        // do a task, such as:
        a[i] = a[i] * number;
    }
}
thread\u count
被初始化为
4
,我尝试对大的
n(>10000)执行它,但是主线程将始终等待其他线程完成for循环的执行,并且只有在
协同工作()返回:printf()时才会继续主线程将始终打印只有一个线程在运行

现在,有什么方法可以从主线程检查其他线程是否仍在运行,如果仍在运行,则执行一些递增操作?

从主线程可以读取:

当一个线程遇到一个并行构造时,一组线程将被激活 创建以执行并行区域遇到的线程 并行构造成为新团队的主线程,具有 新并行区域期间的线程数为零。 新团队中的所有线程,包括主线程,都执行 区域。创建团队后,团队中的线程数 在平行区域的持续时间内保持不变

因此,使用子句
#pragma omp parallel for num_threads
所有线程都将执行并行工作(即,计算循环的迭代),这是您不想要的。为了解决这个问题,您可以实现

`#pragma omp parallel for num_threads`
因为,显式使用上述子句将使编译器自动在团队中的线程之间划分循环的迭代,包括该团队的主线程。代码如下所示:

# pragma omp parallel num_threads(thread_count) shared(a, n, number)
{
      int thread_id = omp_get_thread_num();
      int total_threads = omp_get_num_threads();
      if(thread_id != 0) // all threads but the master thread
      {
        thread_id--; // shift all the ids
        total_threads = total_threads - 1;
        for(long i = thread_id ; i < n; i += total_threads) {
            // do a task, such as:
            a[i] = a[i] * number;
        }
      }
} 
但是,请记住,由于变量
count\u thread\u finished
在线程之间共享,因此您需要确保(例如,使用)其更新,否则将存在争用条件。这会给你足够的时间继续前进

顺便说一句:
schedule(static,n/thread\u count)
通常是不需要的,因为默认情况下,大多数OpenMP实现已经将循环的迭代(在线程之间)划分为连续块

# pragma omp parallel num_threads(thread_count) shared(a, n, number)
{
      int thread_id = omp_get_thread_num();
      int total_threads = omp_get_num_threads();
      if(thread_id != 0) // all threads but the master thread
      {
        thread_id--; // shift all the ids
        total_threads = total_threads - 1;
        for(long i = thread_id ; i < n; i += total_threads) {
            // do a task, such as:
            a[i] = a[i] * number;
        }
      }
} 
// declare two shared variable 
// 1) to count the number of threads that have finished working count_thread_finished
# pragma omp parallel num_threads(thread_count) shared(a, n, number)
{
      int thread_id = omp_get_thread_num();
      int total_threads = omp_get_num_threads();
      if(thread_id != 0) // all threads but the master thread
      {
        thread_id--; // shift all the ids
        total_threads = total_threads - 1;
        for(long i = thread_id ; i < n; i += total_threads) {
            // do a task, such as:
            a[i] = a[i] * number;
        }
        // count_thread_finished++
      }
      else{ // the master thread 
          while(count_thread_finished != total_threads -1){
              // wait for a while....
          }
     }
}