pthread мьютекс не работает, получая случайное значение каждый раз - PullRequest
0 голосов
/ 25 января 2020

Я изучаю pthreads POSIX и, используя мьютекс, я начал получать странные результаты. Каждый раз, когда я запускаю код, он выдает случайное число, а я ожидаю, что он выведет 0. Я проверил код и не смог выяснить причину, по которой это происходит, поэтому, если кто-то может объяснить мне, что именно идет не так, это будет очень признательно.

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

int num = 0;
pthread_mutex_t mutex;

void* add(void* args)
{
    int sign = *(int*) args;
    for(int i = 0; i < 100; i++)
    {
        pthread_mutex_lock(&mutex);
        num += sign;
        pthread_mutex_unlock(&mutex);
    }
    pthread_exit(NULL);
    return NULL;
}


int main()
{
    pthread_t pool[1000];
    int plus = +1;
    int minus = -1;
    pthread_mutex_init(&mutex, NULL);


    for(int i = 0; i < 500; i++)
        pthread_create(&pool[i], NULL, add, &plus);

    for(int i = 500; i < 1000; i++)
        pthread_create(&pool[i], NULL, add, &minus);

    for(int i = 0; i < 1000; i++)
        pthread_join(pool[i], NULL);

    printf("%d", num);
    return 0;
}

1 Ответ

0 голосов
/ 26 января 2020

следующий предложенный код:

  1. без ошибок компилируется
  2. правильно проверяет ошибки
  3. правильно инициализирует мьютекс
  4. выполняет желаемую функциональность
  5. приводит к выводу 0

Примечание: функция: pthread_mutex_init() является допустимой функцией, но начальное значение NULL недопустимо

и Теперь предложенный код:

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

int num = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void* add(void* args)
{
    int sign = *(int*) args;

    for(int i = 0; i < 100; i++)
    {
        pthread_mutex_lock(&mutex);
        num += sign;
        pthread_mutex_unlock(&mutex);
    }

    pthread_exit(NULL);
}


int main( void )
{
    pthread_t pool[1000];
    int plus = +1;
    int minus = -1;


    for(int i = 0; i < 500; i++)
        if( pthread_create(&pool[i], NULL, add, &plus) != 0 )
        {
            perror( "pthread_create failed" );
            pool[i] = 0;
        }


    for(int i = 500; i < 1000; i++)
    {
        if( pthread_create(&pool[i], NULL, add, &minus) != 0 )
        {
            perror( "pthread-create failed" );
            pool[i] = 0;
        }
    }

    for(int i = 0; i < 1000; i++)
    {
        if( pool[i] )
        {
            pthread_join(pool[i], NULL);
        }
    }

    printf("%d", num);
    return 0;
}

Выполнение предложенного кода на linux приводит к:

0
...