您可以在同一个函数中使用多个互斥锁 lock/unlock 和不同的键来计算数据结构中的平均值吗?

Can you use multiple mutex lock/unlock with non-identical keys within the same function to calculate average in a data structure?

假设我想计算大小为 N 的 数组 X 中值的平均值。假设我们使用 T 个线程,其中 T 是 N 的一部分,所以我们是多线程。

是否可以声明两个唯一的互斥键并无误地执行以下操作?

编辑:关于如何计算平均值、最大值、最小值等的任何想法?

见下文:

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

void* sum(void* arg);

int sum = 0;
int average = 0;

int x[N];

int main()
{
    int i;
    pthread_t threads[T];

    for(i=0; i<T; i++)
        pthread_create(&x[i], NULL, sum, (void *)i);
    for(i=0; i<T; i++)
        pthread_join(x[i], NULL);
}

void* sum(void* arg)
{
    int counter = 0;
    int *id = (int *) arg;

    pthread_mutex_t key1;
    pthread_mutex_t key2;

    int size = N/T;
    int start = id * size;
    int end = id * size + size;

    for(i=start; i<end; i++)
    {
        counter = counter + x[i];
    }

    pthread_mutex_lock(&key1);
    sum += counter;
    pthread_mutex_unlock(&key1);

    pthread_mutex_lock(&key2);
    average = sum / counter;
    pthread_mutex_lock(&key2);

    return NULL;
}

不,这是一场灾难。每个线程将调用 sum 并且它们将各自获得自己的互斥锁。这意味着一个线程可以锁定其 key2,同时另一个线程可以锁定其 key2。所以两个线程可以同时访问average

您只需要一个互斥锁来保护 average。否则,它实际上并没有受到保护。

(此外,您同时拥有一个函数和一个名为 sum 的全局变量。这会导致痛苦和混乱。)

你还有一个问题。每个线程都使用共享 sum 并将其除以其私有 counter。那根本没有任何意义。 sum 变量需要除以它求和的条目总数以获得平均值,而不是该特定线程添加的条目数。

我建议进行两项更改:

  1. 只有一个互斥锁。使其成为全球性的。
  2. 没有 sum 函数接触 average 变量。加入所有线程后,只需执行 average = sum / N;.