Moduł pamięci (moduł DIMM) może wykonywać tylko jedną czynność: odczyt lub zapis. Jest to podyktowane protokołem na złączu krawędziowym DIMM; po wysłaniu polecenia odczytu lub zapisu do modułu DIMM nie może on nawet „usłyszeć” kolejnego, dopóki poprzednie polecenie nie zostanie zakończone.
Wszystkie moduły DIMM na wspólnej magistrali pamięci będą wspólnie miały to ograniczenie czasowe. Ale na wielu platformach PC są dwie lub trzy pamięci kanały , a cała pamięć RAM na jednym kanale może wspólnie wykonywać tylko jedną rzecz na raz.
W przypadku maszyn NUMA (tych z wieloma gniazdami procesora i „prywatną” pamięcią dla każdego gniazda) wszystko to jest mnożone przez nCPU. tj. każdy procesor może uzyskać dostęp do swojej lokalnej pamięci niezależnie od tego, co robi inny procesor jego pamięć. Jednak wszystkie procesory mogą nadal uzyskiwać dostęp do całej pamięci RAM, po prostu potrzebuje trochę więcej czasu, aby przejść przez inny procesor.
Zasadniczo do kodu aplikacji należy wdrożenie wszelkich wymagań serializacji dotyczących dostępu do współdzielonych danych. Odbywa się to przy pomocy systemu operacyjnego, który zapewni różne obiekty synchronizacji i funkcje do korzystania z aplikacji. Obiekty te mają nazwy takie jak semafory (nazwa zapożyczona z sygnału kolejowego), muteksy (skrót od „wzajemnego wykluczenia”) itp. W zależności od systemu operacyjnego mogą one implementować pojedynczo, n-na-czasie, Ekskluzywny odczyt a współdzielony odczyt itp., semantyka. Funkcje te zazwyczaj obejmują „czekanie” lub „blokowanie”: wątek próbuje np. zdobyć muteks, który z założenia „chroni” wspólny zasób. Jeśli mutex jest już własnością jakiegoś innego wątku, drugi (i _n_th) wątek żądający jest zablokowany, tzn. Czeka i nie wraca z wywołania pozyskiwania, dopóki poprzedni właściciel go nie zwolni.
Do aplikacji należy stosowanie tych technik w razie potrzeby; system operacyjny nie może wymagać tego np. musisz mieć określony muteks przed uzyskaniem dostępu do danych, które miał chronić muteks. Jest to obszar projektowania programu, który może być bardzo trudny zarówno do uzyskania prawidłowego, jak i wysokiej wydajności.
Podsystemy wyższego poziomu, takie jak bazy danych, mają wbudowane kodowanie danych, którymi zarządzają, i prezentują programistom interfejs, który „mówi” w kategoriach elementów bazy danych, a nie obiektów synchronizacji: programista wywołuje funkcje, aby zablokować wiersz tabeli lub pojedyncza komórka lub zestaw wierszy, a może cała tabela podczas wykonywania aktualizacji. Poniżej bazy danych silnik będzie korzystał z urządzeń systemu operacyjnego, jak opisano wcześniej.
Wewnętrznie system operacyjny zazwyczaj realizuje te funkcje synchronizacji za pomocą pewnego rodzaju atomowej operacji testowania i modyfikacji, która jest zaimplementowana w podsystemie pamięci. Przez „atomowy” mam na myśli to, że raz rozpoczęta operacja jest gwarantowana, zanim zakończy się jakakolwiek inna operacja atomowa w zaatakowanej pamięci. Przykładem powszechnie używanym w systemie Windows jest instrukcja „zablokowane porównanie i wymiana”. x86 / x64 faktycznie udostępnia całą serię takich instrukcji, pracujących na różnych rozmiarach danych.
Istnieją metody, które umożliwiają bezpieczny dostęp szeregowy do współdzielonych danych bez użycia takich technik, ale działają tylko w kilku szczególnych przypadkach (np. „Tylko jeden czytnik i tylko jeden pisarz”) lub dla niektórych typów danych.