Поиск…


Вступление

При написании многопоточных приложений одной из наиболее часто встречающихся проблем являются условия гонки. Итак, мы документируем, как вы их обнаруживаете? и как вы справляетесь с ними?

Пример: рассмотрим два потока T1 и T2.

Как вы их обнаруживаете?

Если одно и то же местоположение переменной / ресурса / памяти доступно для нескольких потоков, и по крайней мере поток изменяет значение места переменной / ресурса / памяти , тогда может возникнуть состояние гонки . Потому что, если поток изменяет значение места переменной / ресурса / памяти, а другой поток пытается прочитать то же самое, то он не получит обновленное значение.

Примечание . Если все потоки просто считывают местоположение переменной / ресурса / памяти, то условие гонки не будет происходить.

Пример: программа страдает от состояния гонки

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

int x= 0;

void* fun(void* in)
{
    int i;
    for ( i = 0; i < 10000000; i++ )
    {
        x++;
    }
}

int main()
{
    pthread_t t1, t2;
    printf("Point 1 >> X is: %d\n", x);

    pthread_create(&t1, NULL, fun, NULL);
    pthread_create(&t2, NULL, fun, NULL);
    pthread_join(t1, NULL);
    pthread_join(t2, NULL);

    printf("Point 2 >> X is: %d\n", x);
    return 0;
}

Выход на моем экране:

Point 1 >> X is: 0
Point 2 >> X is: 9925047

Ваш результат будет отличаться. Но наверняка это не будет 20 000 000. Поскольку оба потока выполняли один и тот же цикл и имели глобальную переменную int x;

for ( i = 0; i < 10000000; i++ )
{
   x++; 
}

Таким образом, конечное значение x в строке Point 2 >> X is: 9925047 должно быть 20 000 000. Но это не так.

Состояние x может быть изменено другим потоком за время чтения x и когда оно будет записано обратно.

Предположим, что поток получает значение x, но еще не сохранил его. Другой поток также может получить одно и то же значение x (потому что ни один нить не изменил его), а затем они оба сохраняют одно и то же значение (x + 1) обратно в x!

Пример:

Тема 1: читает x, значение равно 7

Тема 1: добавить 1 в x, теперь значение 8

Thread 2: читает x, значение равно 7

Тема 1: хранит 8 в x

Тема 2: добавляет 1 к x, теперь значение 8

Тема 2: сохраняет 8 в x

Как вы справляетесь с ними?

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

Ниже приведена измененная программа:

Пример: проблема с расой

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

int x= 0;
//Create mutex
pthread_mutex_t test_mutex;

void* fun(void* in)
{
    int i;
    for ( i = 0; i < 10000000; i++ )
    {
        //Lock mutex before going to change variable
        pthread_mutex_lock(&test_mutex);
        x++;
        //Unlock mutex after changing the variable
        pthread_mutex_unlock(&test_mutex);
    }
}

int main()
{
    pthread_t t1, t2;
    printf("Point 1 >> X is: %d\n", x);

    //Initlize mutex
    pthread_mutex_init(&test_mutex, NULL);

    pthread_create(&t1, NULL, fun, NULL);
    pthread_create(&t2, NULL, fun, NULL);
    pthread_join(t1, NULL);
    pthread_join(t2, NULL);

    //Destroy mutex after use
    pthread_mutex_destroy(&test_mutex);
    printf("Point 2 >> X is: %d\n", x);
    return 0;
}

Ниже приведен вывод:

Point 1 >> X is: 0
Point 2 >> X is: 20000000

Здесь ответ приходит как 20 000 000 каждый раз.

Примечание . Измененная программа, свободная от ошибки состояния гонки, займет много времени, чтобы выполнить ее. Потому что есть перегрузка на блокировку и разблокирование mutex .



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow