LINUX.ORG.RU

История изменений

Исправление KivApple, (текущая версия) :

Пояснение почему потоки нельзя завершать в произвольный момент времени.

Представь себе функцию удаления элемента из двунаправленного кольцевого связанного списка (на его месте мог бы быть обычный связанный список, просто у двунаправленного кольцевого самый простой алгоритм удаления элемента, а я ленивый):

void remove(ListItem **head, ListItem *item) {
    item->next->prev = item->prev;
    item->prev->next = item->next;
    if (item == *head) {
        *head = item->next;
        if (item == *head) {
            *head = nullptr;
        }
    }
}

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

Или, например, если поток захватил mutex и выполняет какие-то манипуляции с общими данными. Mutex как раз потому и нужен, потому что если другие треды увидят незаконченные модификации, то сойдут с ума. Так что нельзя просто освободить все mutex при убийстве потока. А если их не освободить, то будет dead lock. Ждать освобождения mutex? Это может занять много времени, плюс может быть алгоритм, который постоянно захватывает разные mutex и в каждый момент времени владеет хоть одним.

Исправление KivApple, :

Пояснение почему потоки нельзя завершать в произвольный момент времени.

Представь себе функцию удаления элемента из двунаправленного кольцевого связанного списка:

void remove(ListItem **head, ListItem *item) {
    item->next->prev = item->prev;
    item->prev->next = item->next;
    if (item == *head) {
        *head = item->next;
        if (item == *head) {
            *head = nullptr;
        }
    }
}

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

Или, например, если поток захватил mutex и выполняет какие-то манипуляции с общими данными. Mutex как раз потому и нужен, потому что если другие треды увидят незаконченные модификации, то сойдут с ума. Так что нельзя просто освободить все mutex при убийстве потока. А если их не освободить, то будет dead lock. Ждать освобождения mutex? Это может занять много времени, плюс может быть алгоритм, который постоянно захватывает разные mutex и в каждый момент времени владеет хоть одним.

Исходная версия KivApple, :

Пояснение почему потоки нельзя завершать в произвольный момент времени.

Представь себе функцию удаления элемента из двунаправленного кольцевого связанного списка:

void remove(ListItem **head, ListItem *item) {
    item->next->prev = item->prev;
    item->prev->next = item->next;
    if (item == *head) {
        *head = item->next;
        if (item == *head) {
            *head = nullptr;
        }
    }
}

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

Или, например, если поток захватил mutex и выполняет какие-то манипуляции с общими данными. Mutex как раз потому и нужен, потому что если другие треды увидят незаконченные модификации, то сойдут с ума. Так что нельзя просто освободить все mutex при убийстве потока. А если их не освободить, то будет dead lock.