Второй поток не войдет во второй цикл - PullRequest
0 голосов
/ 05 июня 2018

У меня проблема с моими темами.Я пытаюсь найти максимальный элемент главной диагонали в двумерном массиве.Первый pthread сделает свое дело и найдет элемент max.Но когда второй и третий и так далее массив «присоединяется к партии», они не будут входить во второе время.Моя функция выглядит следующим образом:

void* findMax() {
    //int t = 1;

    //*arr.times = 0;

    for (*arr.countI = 0; *arr.countI < *arr.l; (*arr.countI)++) {
        for (*arr.countJ = 0; *arr.countJ < *arr.l; (*arr.countJ)++) {
            printf("%d ", arr.a[*arr.countI][*arr.countJ]);
            if (*arr.l - *arr.countJ == 1)
                printf("\n");
        }
    }

    *arr.countI = 0;
    *arr.countJ = 0;

    while (*arr.countI != *arr.l) {
        while (*arr.countJ != *arr.l) {
            if (*arr.countI == *arr.countJ) {
                if (abs(arr.a[*arr.countI][*arr.countJ]) > *arr.max)
                    *arr.max = abs(arr.a[*arr.countI][*arr.countJ]);
            }

            ++(*arr.countJ);
        }

        ++(*arr.countI);

        /*if (++(*arr.times) == 1) {
            *arr.times = 0;
            break;
        }*/
    }

    printf("max = %d\n", *arr.max);
}

Так что, если я введу этот массив

 4 1 1
 1 6 1
 1 1 3

, макс будет равен 4, что, конечно, неправильно.

arr является структурой (глобальной), в которой есть все, что мне нужно;arr.a - это массив.

За последние пару дней я много с ним связывался, но без удачи ...

1 Ответ

0 голосов
/ 06 июня 2018

Как уже отмечалось в комментариях, у вас нет взаимного исключения, поэтому все ваши потоки заняты манипулированием элементами глобального массива независимо от того, что делают другие потоки.

Все эти *arr.countIи т.д. ссылки уродливы.Где взаимное исключение, которое гарантирует, что ни один поток не изменяет что-либо внутри arr, в то время как другой поток также изменяет это?Например, у вас *arr.countI = 0;, но нет видимого взаимного исключения.У вас *arr.max = abs(arr.a[*arr.countI][*arr.countJ]); и нет взаимного исключения.У вас ++(*arr.countJ); и нет взаимного исключения.Ни одна из тем не имеет ни малейшего представления о том, что происходит.Может быть, вам повезло и *arr.countI == *arr.l, поэтому они не входят в петлю.Но у вас нет контроля параллелизма, так что все гадание.

Я думаю, вам следует прекратить использовать countI и countJ из глобальных данных, а также arr.max большую часть времени.Они должны быть заменены локальными переменными для каждого потока (int i; int j; int max;).Если вы сканируете вниз по главной диагонали, вам не нужны вложенные циклы - вы можете просто уменьшить диагональ.Ваш код очень сложен для очень простой работы.Вам все еще нужен мьютекс, чтобы можно было надежно установить *arr.max.arr.a и *arr.l в порядке (но почему указатель *arr.l?), Потому что вы их не изменяете.Вы обещаете вернуть void * и ничего не вернуть.Ложь вашему компилятору - это плохая идея ™.

Если ваши потоки хранят что-либо в вашей глобальной структуре (arr), вам нужно убедиться, что существует взаимное исключение.Я предполагаю, что у вас есть или добавлен член mtx, который является указателем на pthread_mutex_t, который инициализируется до вызова функций потока.Я также предполагаю, что ваша findMax() функция вызывается из pthread_create() (и передается ей в виде указателя функции).

Вы можете использовать гораздо более простой код для задачи, например:

void *findMax(void *arg)
{
    assert(arg == 0);

    for (int i = 0; i < *arr.l; i++) {
        for (int j = 0; j < *arr.l; j++) {
            printf("%d ", arr.a[i][j]);
        }
        printf("\n");
    }

    int max = abs(arr.a[0][0]);
    for (int i = 1; i < *arr.l; i++)
    {
        int absval = abs(arr.a[i][i]);
        if (absval > max)
            max = absval;
    }

    if (pthread_mutex_lock(arr.mtx) == 0)
    {
        *arr.max = max;
        pthread_mutex_unlock(arr.mtx);
    }

    printf("max = %d\n", *arr.max);
    return 0;
}

Предупреждение: некомпилированный код!

...