В чем разница между безопасными, обычными и атомарными регистрами? - PullRequest
16 голосов
/ 15 января 2012

Кто-нибудь может дать исчерпывающее объяснение, пожалуйста? Я углубляюсь в параллельное программирование и знакомлюсь с этими регистрами, пытаясь понять консенсус.

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

Предположим, что первым приходит thread0.write(0) - без перекрытия. В принципе, используя определение Лампорта, можно сказать, что thread1 может сначала прочитать 1 , а затем снова 0 , если оба чтения являются последовательными и перекрываются с thread0.write(1). Но как это возможно?

1 Ответ

31 голосов
/ 16 января 2012

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

, например

Thread 1:      wwwww     wwwww
Thread 2:   rrrrr              rrrrr
Thread 3:   rrrrr rrrrr

Первое чтение из потока 2 перекрывается с первой записью из потока 1, тогда как второе чтение и вторая запись не перекрываются. В потоке 3 оба чтения перекрывают первую запись.

Регистр

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

A обычный регистр добавляет дополнительную гарантию того, что если чтение перекрывается с записью, то оно будет либо читать старое значение, либо новое, но множественные чтения, которые перекрывают запись, не должны согласовывать который, и значение может показаться «мерцающим» взад и вперед. Это означает, что два чтения из одного и того же потока (например, из потока 3 выше), которые оба перекрывают запись, могут выглядеть «не по порядку»: более раннее чтение возвращает новое значение, а позднее возвращает старое значение.

Регистр atomic гарантирует, что чтение и запись, по-видимому, происходят в один момент времени. Читатели, которые действуют в точке до этой точки, будут все читать старое значение, а читатели, которые действуют после этой точки, будут читать новое значение. В частности, если два чтения из одного и того же потока перекрывают запись, то позднее чтение не может вернуть старое значение, если более раннее чтение возвращает новое. Атомные регистры линеаризуемы .

Искусство многопроцессорного программирования Мориса Херлихи и Нира Шавита дает хорошее описание, а также примеры и варианты использования.

...