Получите блокировку на двух взаимных исключениях и избегайте мертвой блокировки

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

void foo::copy(const foo & rhs)
{
    pMutex->lock();
    rhs.pMutex->lock();
    // do copy
}

Нечто имеет контейнер STL, и "действительно копируют", по существу состоит из использования станд.:: копия. Как я блокирую оба взаимных исключения, не представляя мертвую блокировку?

10
задан pomeroy 12 February 2010 в 03:53
поделиться

3 ответа

Наведите какой-то полный порядок на экземпляры foo и всегда получайте их блокировки в порядке возрастания или убывания, например. , foo1-> lock () , а затем foo2-> lock () .

Другой подход - использовать функциональную семантику и вместо этого написать метод foo :: clone , который создает новый экземпляр, а не уничтожает существующий.

Если ваш код выполняет много блокировок, вам может потребоваться сложный алгоритм предотвращения взаимоблокировок, такой как алгоритм банкира .

15
ответ дан 3 December 2019 в 23:50
поделиться

Как насчет этого?

void foo::copy(const foo & rhs)
{
    scopedLock lock(rhs.pMutex); // release mutex in destructor
    foo tmp(rhs);
    swap(tmp); // no throw swap locked internally
}

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

1
ответ дан 3 December 2019 в 23:50
поделиться
  1. Добавьте в решение новый проект установки.
  2. Добавьте конечные объекты из всех проектов, которые требуется установить.
  3. Настройте предварительные требования и выберите параметр «Проверить наличие .NET 3.5 и SQL Express». Выберите расположение, в котором должны быть установлены отсутствующие компоненты.
  4. Настройте параметры настройки программы установки - название компании, версия, авторские права и т.д.
  5. Создавайте и отправляйте!
-121--980377-

Это не очень эффективно, и есть гораздо лучшие способы сделать это в целом (см. ответ @ Anurag), но это просто и хорошо работает для коротких последовательностей:

function stringIntersection(str1, str2) {
    var strTemp;

    // Swap parameters if necessary to ensure str1 is the shorter
    if (str1.length > str2.length) {
        strTemp = str1;
        str1 = str2;
        str2 = strTemp;
    }

    // Start with the whole of str1 and try shorter substrings until
    // we have a common one
    var str1Len = str1.length, l = str1Len, start, substring;
    while (l > 0) {
        start = str1Len - l;
        while (start >= 0) {
            substring = str1.slice(start, l);
            if (str2.indexOf(substring) > -1) {
                return substring;
            }
            start--;
        }
        l--;
    }
    return "";
}

var s1 = "Here is a quick guide for the next time you reach"
       + " for your favorite oil and some other topics";
var s2 = "favorite oil and some other topics can be based on"
       + " something blah blah";

alert( stringIntersection(s1, s2) );
-121--4268352-

Чтобы избежать взаимоблокировки, следует дождаться блокировки обоих ресурсов:

Не знайте, какой API мьютекса вы используете, так что здесь есть некоторый произвольный псевдокод, предположим, что can _ lock () проверяет только, может ли он заблокировать мьютекс, и что try _ lock () возвращает true, если он заблокирован, и false, если мьютекс уже заблокирован кем-то другим.

void foo::copy(const foo & rhs)
{
    for(;;)
    {
        if(! pMutex->cany_lock() || ! rhs.pMutex->cany_lock())
        {
            // Depending on your environment call or dont call sleep()
            continue;
        }
        if(! pMutex->try_lock())
            continue;
        if(! rhs.pMutex->try_lock())
        {
            pMutex->try_lock()
            continue;
        }
        break;
    }
    // do copy
}
-1
ответ дан 3 December 2019 в 23:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: