När två processorer försöker få tillgång till samma plats i globalt minne på samma ögonblick, ett
race -tillstånd inträffar. Resultatet beror helt på systemets minnesarkitektur och hur det hanterar samtidig åtkomst. Det finns flera möjligheter:
* odefinierat beteende: Detta är det värsta fallet. Resultatet av minnesåtkomst är oförutsägbart. En processors skrivning kan skriva över den andra, eller delar av båda kan vara sammanflätade, vilket leder till skadade data. Det finns ingen garanti för vilken processors operation som kommer att lyckas eller hur uppgifterna kommer att påverkas. Detta är vanligt i system utan någon minnesåtkomstsynkroniseringsmekanismer.
* Datakorruption: En processors skrivning kan skriva över de data som skrivs av den andra processorn, vilket resulterar i förlorade data eller felaktiga värden. Detta är ett mycket vanligt resultat om det inte finns någon synkronisering.
* godtyckligt resultat: Systemets hårdvara eller operativsystem kan välja en processors åtkomst för att lyckas och det andra att misslyckas, eller det kan kombinera operationerna på ett oväntat sätt. Resultatet är inte deterministiskt.
* Hårdvaranivå Arbitration: Vissa arkitekturer kan ha hårdvarumekanismer (som en busarbiter) som prioriterar en processor framför den andra. Detta introducerar ett icke-deterministiskt element, eftersom prioriteringen kan variera beroende på olika faktorer.
* Undantag/fel: Systemet kan upptäcka konflikten och höja ett undantag eller fel, potentiellt stoppa körningen eller få programmet att krascha. Detta är dock inte garanterat; Många system tillåter helt enkelt tävlingsvillkoret att fortsätta utan anmälan.
För att förhindra dessa problem måste programmerare använda synkroniseringsmekanismer. Dessa mekanismer upprätthåller beställning av minnesåtkomst, vilket förhindrar rasförhållanden. Exempel inkluderar:
* mutexes (ömsesidig uteslutning): Endast en processor kan hålla mutex vid en viss tidpunkt och förhindra samtidig tillgång till delade resurser.
* Semaphores: Mer allmänt än mutexer, vilket möjliggör mer komplex kontroll av tillgången till delade resurser.
* atomiska operationer: Operationer som garanteras att utföras atomiskt (som en enda, odelbar enhet), vilket förhindrar samtidig modifiering.
* Minnesbarriärer/staket: Dessa verkställer beställning av minnesoperationer, vilket säkerställer att vissa operationer genomförs innan andra börjar.
Kort sagt, samtidig tillgång till samma minnesplats utan korrekt synkronisering är ett allvarligt programmeringsfel som kan leda till oförutsägbart och opålitligt beteende. Robust programmering med flera processor kräver noggrant övervägande och implementering av synkroniseringstekniker.