Увеличение общей переменной не возвращает ожидаемый результат после блокировки мьютекса

Я вызываю 100 потоков, и каждый поток должен увеличивать общую переменную 1000 раз. Таким образом, ожидаемый результат должен быть равен 100 000. Конечно, когда несколько потоков пытаются увеличить одну общую переменную, вы также можете получить результаты, отличные от 100 000 (маловероятно, что вы сможете получить 100 000).

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

Тем не менее, я все еще получаю числа, такие как 99000, 98000, а иногда и 100000. Но это всегда должно быть 100000, потому что у меня есть блокировка, верно?

Это то, что у меня есть

volatile unsigned int count = 0;

void *increment(void *vargp);
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

int main() {
    fprintf(stdout, "Before: count = %d\n", count);

    int j;
    // run 10 times to test output
    for (j = 0; j < 10; j++) {
        // reset count every time
        count = 0;

        int i;
        // create 100 theads
        for (i = 0; i < 100; i++) {
            pthread_t thread;

            Pthread_create(&thread, NULL, increment, NULL);
        }

        fprintf(stdout, "After: count = %d\n", count);
    }

    return 0;
}          

void *increment(void *vargp) {
    int c;

    // protected by mutex lock
    pthread_mutex_lock(&mutex);

    // increment count 1000 times
    for (c = 0; c < 1000; c++) {
        count++;
    }

    pthread_mutex_unlock(&mutex);

    return NULL;
}    

person PTN    schedule 22.08.2015    source источник
comment
всегда проверяйте возвращаемое значение при вызове pthread_create(), чтобы убедиться, что операция прошла успешно   -  person user3629249    schedule 24.08.2015
comment
при возврате/выходе из потока используйте 'pthread_exit(*status);' обратите внимание на возврат( NULL );   -  person user3629249    schedule 24.08.2015
comment
код отсутствует (в функции main()) 100 вызовов pthread_join() и имеет только 1 запись для идентификаторов потоков. для идентификаторов требуется 100 записей, поэтому вызовы pthread-join() работают правильно.   -  person user3629249    schedule 24.08.2015
comment
Я заметил, что pthread_create() пишется как «Pthread_create()», что, вероятно, неверно.   -  person user3629249    schedule 24.08.2015
comment
для каждого запущенного потока функция main() нуждается в вызове pthread_join(), чтобы дождаться завершения потока   -  person user3629249    schedule 24.08.2015
comment
вы включили нужный заголовочный файл?   -  person user3629249    schedule 24.08.2015


Ответы (2)


Вы ждете, пока все потоки закончатся? Не похоже, что ты. Попробуйте что-то вроде Как я могу дождаться любых/всех pthreads завершить?

person DavidN    schedule 22.08.2015

следующий код, запущенный в Ubuntu Linux 14.04, компилируется чисто и работает правильно.

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

#define UNUSED(x)      (void)(x)
#define NUM_TESTS      (10)
#define NUM_INCREMENTS (1000)
#define NUM_THREADS    (100)

volatile unsigned int count = 0;

void *increment(void *vargp);

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

int main( void )
{
    fprintf(stdout, "Before: count = %d\n", count);

    pthread_t thread[NUM_THREADS];
    int j;

    // run 10 times to test output
    for (j = 0; j < NUM_TESTS; j++)
    {
        // reset count every time
        count = 0;

        int i;
        // create 100 theads
        for (i = 0; i < NUM_THREADS; i++)
        {
            pthread_create(&thread[i], NULL, increment, NULL);
        }

        for( i=0; i < NUM_THREADS; i++ )
        {
            void *retval;
            pthread_join( thread[i], &retval);
        }

        fprintf(stdout, "After: count = %d\n", count);
    }

    return 0;
}

void *increment(void *vargp)
{
    UNUSED(vargp);
    int c;

    // protected by mutex lock
    pthread_mutex_lock(&mutex);

    // increment count 1000 times
    for (c = 0; c < NUM_INCREMENTS; c++)
    {
        count++;
    }

    pthread_mutex_unlock(&mutex);

    pthread_exit( NULL );
}
person user3629249    schedule 24.08.2015