Я новичок в многопоточном программировании, и я пытался кодировать Bakery Lock Algorithm в C.Bakery блокировки при использовании внутри структуры не работает
Вот код:
Тогда Я приведу следующий пример. Я бегу 100 потоков и каждый поток работает следующий код:
for (i = 0; i < 10; ++i) {
lock(id);
counter++;
unlock(id);
}
После того как все нити были выполнены, результат общего counter
является 10 * 100 = 1000
что ожидаемое значение. Я выполнил свою программу несколько раз, и результат всегда был 1000
. Таким образом, кажется, что реализация блокировки правильная. Это казалось странным на основе previous question, потому что я не использовал никаких барьеров/ограждений. Было ли мне повезло?
Тогда я хотел создать многопоточную программу, которая будет использовать множество разных замков. Так что я создал это (полный код можно найти here):
typedef struct {
int number[N];
int choosing[N];
} LOCK;
и изменения кода на:
void lock(LOCK l, int id)
{
l.choosing[id] = 1;
l.number[id] = max(l.number, N) + 1;
l.choosing[id] = 0;
...
Теперь при выполнении моей программы, иногда я получаю 997
, иногда 998
, иногда 1000
. Поэтому алгоритм блокировки неверен.
Что я делаю неправильно? Что я могу сделать, чтобы исправить это?
Это, возможно, проблема теперь, когда я читаю массивы number
и choosing
из struct
и это не атомная или что-то?
Должен ли я использовать заграждения памяти, и если да, то в каких точках (я пытался использовать asm("mfence")
в разных точках моего кода, но это не помогло)?
Надеюсь, это всего лишь академическое упражнение, а не то, что вы на самом деле пытаетесь использовать ... –
@R .. Я бы не использовал на практике блокировку пекарни на практике :). Это тоже не упражнение. Я просто пытаюсь привыкнуть к работе с многопоточными программами. –
@Fooko R. Если это так, не используйте такие примитивы, как блокировка. Используйте стандартные, работающие и проверенные API/библиотеки. – nos