У меня есть 2 вопроса относительно нитей, один - о состоянии гонки, а другой - о мьютексе. Поэтому первый вопрос: Я прочитал о расе состоянии в википедии странице: http://en.wikipedia.org/wiki/Race_conditionСостояние гонки и мьютексы
И в примере гонки состоянии между 2 нитями это показано на рисунке: http://i60.tinypic.com/2vrtuz4.png[
Сейчас до сих пор я считал, что потоки работают параллельно друг другу, но, судя по этой картине, кажется, что я интерпретировал, как действия, выполняемые компьютером, ошибочны. С этой картинки выполняется только одно действие за раз, и хотя потоки время от времени переключаются, а другой поток выполняет некоторые действия, это все равно 1 действие за раз, выполненное компьютером. Неужели это так? Нет «реальных» параллельных вычислений, всего лишь одно действие за один раз с очень высокой скоростью, что дает иллюзию параллельных вычислений?
Это приводит меня к моему второму вопросу о мьютексе. Я читал, что если потоки читают/записывают в одну и ту же память, нам нужен какой-то механизм синхронизации. Я читал, что обычные типы данных не будут делать, и нам нужен мьютекс. Давайте возьмем для примера следующего кода:
#include <stdio.h>
#include <stdbool.h>
#include <windows.h>
#include <process.h>
bool lock = false;
void increment(void*);
void decrement(void*);
int main()
{
int n = 5;
HANDLE hIncrement = (HANDLE)_beginthread(increment, 0, (void*)&n);
HANDLE hDecrement = (HANDLE)_beginthread(decrement, 0, (void*)&n);
WaitForSingleObject(hIncrement, 1000 * 500);
WaitForSingleObject(hDecrement, 1000 * 500);
return 0;
}
void increment(void *p)
{
int *n = p;
for(int i = 0; i < 10; i++)
{
while (lock)
{
}
lock = true;
(*n)++;
lock = false;
}
}
void decrement(void *p)
{
int *n = p;
for(int i = 0; i < 10; i++)
{
while (lock)
{
}
lock = true;
(*n)--;
lock = false;
}
}
Теперь в моем примере здесь, я использую замок Его как мой механизм синхронизации, чтобы избежать состояний гонки между 2 нитями над пространством памяти, указываемым указателем п. Теперь то, что я здесь сделал, очевидно, не будет работать, потому что, хотя я избежал условия гонки по пространству памяти, указанному указателем n между двумя потоками, может возникнуть новое состояние гонки по переменной блокировки bool.
Давайте рассмотрим следующую последовательность событий (А = прибавка нить, B = декремент нить):
- А получает из цикла в то время, так как замок является ложным
- А получает установить блокировку на истинный
- B ожидает в то время цикла, потому что замок установлен в положении истинного
- приращения значения указывало на п
- А установлена замок ложную
- А получает к петле в то время как
- А получает из цикла в то время, так как замок является ложным
- Б выходит из цикла в то время, так как замок является ложным
- А установлена блокировка истинных
- наборов B блокировки для правда
и отсюда мы получаем неожиданное поведение-не-синхронизированные потоков, поскольку блокировка BOOL не состояние гонки доказательства.
Хорошо, это мое понимание и решение нашей проблемы выше, нам нужно мьютекс. Я в порядке с этим, тип данных, который волшебным образом будет служить доказательством гонки. Я просто не понимаю, как с помощью метода mutex этого не произойдет, когда, как и в случае с любым другим типом, он будет и здесь будет моей проблемой, я хочу понять, почему мьютекс и как это происходит.
Вы можете * иметь несколько потоков, работающих одновременно в многопроцессорной системе. – EOF
Вы не можете использовать SO, чтобы изучить новые знания, такие как потоки. Я предлагаю вам найти хороший сайт и учебник и начать учиться. Ваш вопрос показывает, что вы абсолютно не знаете, что такое потоки или как это работает. –
Я интерпретирую это как вполне правильный вопрос, хотя и с большим количеством дополнительной экспозиции вокруг него, что, вероятно, является результатом слабого смущения незнакомого контекста (я замечаю ту же тенденцию в своих собственных вопросах). Итак, я думаю, что @ Omlis532 - это вопрос: «Как может существовать тип mutex threadafe, когда все базовые типы не являются потокобезопасными?» – Medo42