您是否可以在同一函数中使用多个互斥锁定/解锁与非相同的键来计算数据结构中的平均值?

时间:2017-11-17 06:13:32

标签: c arrays multithreading mutex

我想要计算数组大小为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;
}

1 个答案:

答案 0 :(得分:1)

不,这是一场灾难。每个帖子都会调用sum,每个帖子都会获得自己的互斥锁。这意味着一个线程可以在另一个线程锁定其key2的同时锁定其key2。因此,两个线程可以同时访问average

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

(另外,你有一个函数和一个名为sum的全局。这会导致痛苦和混乱。)

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

我建议做两处修改:

  1. 只有一个互斥锁。让它成为一个全球性的。
  2. 没有sum功能触及average变量。加入所有主题后,只需average = sum / N;