c - 我如何让 C 中的多个线程处理二维数组的同一个 for 循环?

标签 c multithreading concurrency pthreads mutex

我有一个 C 语言的程序。

我已经使用 pthread_create 创建了 3 个线程,并且创建了一个互斥体 为了锁定/解锁关键区域。

pthread_create第三个参数 是指向线程将执行的函数的指针。

在我在网上找到的示例中,此函数总是非常简单,例如打印线程 ID 或打印消息。

当线程要执行的函数包含for 循环时会发生什么?

因为在我的程序中,我希望每个线程都使用一个二维数组。

每个线程求一个二维数组的一行的和。 例如

Thread1要计算二维数组第一行的和

Thread2 应计算第二行的总和
Thread1 应计算第 3 行的总和
Thread3 应计算第 3 行的总和

我不关心线程的顺序,但我需要每一个 线程选择其中一行。

我有以下代码求和二维数组中的两个单元格。

程序:

  1. 创建 NTHREADS

     for(i=0; i < NTHREADS; i++)
        {
           pthread_create( &thread_id[i], NULL, CalculateSum, NULL );
        }
    
  2. 每个线程等待其他线程完成

    for(j=0; j < NTHREADS; j++)
       {
          pthread_join( thread_id[j], NULL);
       }
    
  3. 除了数组的ONE 和整个数组的NOT,每个线程应该执行的函数是

    void *CalculateSum(void *dummyPtr)
    {
       pthread_mutex_lock( &mutex1 );
    
     int i,j,sum = 0;
    
      for( i = 0; i <= N-1; i++) {
            for( j = 0; j <= M-1; j++) {
                    sum = dimensional_array[i][j] + dimensional_array[i][j];
            }
             printf(" Sum = %d\n", sum);
            }
    
       counter++;
    
       pthread_mutex_unlock( &mutex1 );
    }
    

整个程序如下: 该程序没有任何编译错误。

为了运行它你应该做:gcc -pthread program.c

    //program.c

   #include <stdio.h>
   #include <pthread.h>

   #define NTHREADS 3
   void *CalculateSum(void *);
   pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
   int  counter = 0;

   #define N 10
   #define M 10

   int dimensional_array[N][M];

   main()
   {
      pthread_t thread_id[NTHREADS];
      int i, j;

      for (i = 0; i <= N - 1; i++ )
           for( j = 0; j <= M - 1; j++)
                   dimensional_array[i][j] = i;

      for(i=0; i < NTHREADS; i++)
      {
         pthread_create( &thread_id[i], NULL, CalculateSum, NULL );
      }

      for(j=0; j < NTHREADS; j++)
      {
         pthread_join( thread_id[j], NULL);
      }



      printf("Final counter value: %d\n", counter);

      //print ARRAY
      for (i = 0; i <= N-1; i++ ) {
           for( j = 0; j <= M-1; j++)
                   printf("%d\t",dimensional_array[i][j]);
           printf("\n");
           }
   }
   //Calculate
   void *CalculateSum(void *dummyPtr)
   {
      pthread_mutex_lock( &mutex1 );

    int i,j,sum = 0;

     for( i = 0; i <= N-1; i++) {
           for( j = 0; j <= M-1; j++) {
                   sum = dimensional_array[i][j] + dimensional_array[i][j];
           }
            printf(" Sum = %d\n", sum);
           }

      counter++;

      pthread_mutex_unlock( &mutex1 );
   }

所以,我希望每个线程都能找到一行的总和,但我很困惑,我不知道 怎么做。

在我的程序中,每次线程调用 Calculate 函数时,都会计算所有行的总和,而不仅仅是一个

[注意:为简单起见,我将第一个元素与其自身相加,重点是理解 这些线程如何在那个 for 循环中发生]

如果有人能帮助我,我会很高兴

提前致谢

最佳答案

您应该创建一个线程参数数组,并将这些参数一个一个地传递给线程。在您的情况下,指向 int 的单个指针就足够了:您将其索引 threadindex 从零传递给线程 NTHREADS,然后线程传回满足 row % NTHREADS == threadindex 的行的总和。

这是你的线程函数的样子:

void *CalculateSum(void *args)
{
    int *argPtr = args;

    int i,j,sum = 0;
    int threadindex = *argPtr;

    for( i = 0; i <= N-1; i++) {
        if (i % NTHREADS != threadindex) continue;
        for( j = 0; j <= M-1; j++) {
            sum += dimensional_array[i][j];
        }
    }

    pthread_mutex_lock( &mutex1 ); Mutex must go here
    counter++;
    pthread_mutex_unlock( &mutex1 );
    // Pass the value back:
    *argPtr = sum;
}


main()
{
    pthread_t thread_id[NTHREADS];
    int thread_args[NTHREADS];
    int i, j;

    pthread_mutex_init(&mutex1, NULL);

    for (i = 0; i <= N - 1; i++ )
        for( j = 0; j <= M - 1; j++)
            dimensional_array[i][j] = i;

    for(i=0; i < NTHREADS; i++)
    {
        thread_args[i] = i;
        pthread_create( &thread_id[i], NULL, CalculateSum, &thread_args[i]);
    }

    int sum = 0;
    for(j=0; j < NTHREADS; j++)
    {
        pthread_join( thread_id[j], NULL);
        sum += thread_args[i];
    }

    printf("Final counter value: %d. Total: %d\n", counter, sum);
}

关于c - 我如何让 C 中的多个线程处理二维数组的同一个 for 循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13422394/

相关文章:

C双指针

c - 如何在循环外部结构的同时循环结构内部的结构 C 程序

c - 未定义行为或非未定义行为

java - Java中有原子方法的实现吗?

go - 在 Go Playground 上没有得到预期的结果

Java:Runnable 和方法的执行。他们应该在哪里?这有关系吗?

c - 发出宏来打印整数的大小和范围

c# - 在 C#/WPF 中从线程显示 MessageBox,就像它来自主线程一样

c# - 使类的属性线程安全的最佳实践是什么?

java - 关闭后如何重用线程池