Semafor (datalogi)

Inden for datalogi er en semafor en speciel heltalsvariabel. En tælle-semafor er en tællervariabel, som altid kan tælles op, men som kun kan tælles ned, hvis den har en værdi, der er større end nul. Hvis en proces i et program forsøger at tælle længere ned end nul, vil processen blive blokeret indtil en anden proces forøger tælleren. En binær semafor kan kun antage værdierne 0 og 1. En binær semafor kaldes også en mutex, hvilket er en sammentrækning af mutual exclusion, gensidig udelukkelse. En semafor kan anvendes i datalogi som det basale synkroniseringsprimitiv i den datalogiske disciplin parallelprogrammering.

Semaforer kræver understøttelse i computerens styresystem. Styresystemet sørger for, at de rette processer tvinges til at vente indtil, der er sket den nødvendige optælling. Semaforer stilles typisk til rådighed via et programbibliotek som eksempelvis libc i UNIX styresystemer. Læsning og ændring af semaforens værdi er en atomar operation. Det indebærer, at hvis en proces har læst en semafor med værdien 1 i forbindelse med en nedtælling, så er andre udelukket fra at læse denne værdi før nedtællingen er gennemført. Det samme gælder, når semaforen tælles op.

Historie 
Semaforer blev første gang beskrevet og brugt af Edsger Dijkstra. Han beskrev først den binære semafor og beskrev den generelle udgave senere. Dijkstra formulerede også en række abstrakte problemstillinger, som kræver synkronisering. Blandt problemstillingerne er De spisende filosoffer og producent-forbrugerproblemet.

Eksempel på anvendelse 
Semaforer kan bruges når man vil lave kritiske sektioner i et program. En kritisk sektion er en del af et program, som ikke må bruges af flere brugere samtidigt. Med pseudokode kunne det se sådan ud: (Det antages at semaforen sem har startværdien 1 inden proces A og B startes)

 Proces A:
 
 ned( sem )
 a = x
 a = a + 3
 x = a
 op( sem )

 Proces B
 
 ned( sem )
 b = x
 b = b – 5
 x = b
 op( sem )

Semaforen sikrer, at opdateringerne fra de to processer ikke blandes sammen. Uden semaforer kunne der ske følgende:

 x læses i proces A
 x læses i proces B
 a = a + 3
 x sættes til a i proces A
 b = b – 5
 x sættes til b i proces B

Resultatet bliver, at den første opdatering går tabt. Med semaforer ville der i stedet ske følgende:

 Semaforen tælles ned i proces A
 Beregningen påbegndes i proces A
 Semaforen tælles ned i proces B.
 Da semaforen er nul, kan nedtællingen ikke gennemføres, og proces B må vente
 Beregningen gøres færdig i proces A
 Semaforem tælles op i proces A
 Proces B får mulighed for at fortsætte og semaforen tælles ned igen
 Proces B gennemfører beregningen
 Semaforen tælles op i proces B

Semaforen sikrer, at de to opdateringer sker hver for sig, men rækkefølgen kan ikke garanteres.

Baglås 
Hvis semaforer ikke bruges korrekt, kan der opstå situationer, hvor programmerne går i baglås. Det kan ske, hvis forskellige processer bruger forskellige semaforer, men ikke bruger dem i samme rækkefølge. Eksempel:

 Proces A
 
 ned(sem1)
 .
 ned(sem2)
 .
 .
 op(sem2)
 op(sem1)

 Proces B
 
 ned(sem2)
 ned(sem1)
 .
 .
 op(sem1)
 op(sem2)

Systemet kan gå i baglås på følgende måde:

 Proces A tæller sem1 ned
 Proces B tæller sem2 ned
 Proces B venter på sem1
 Proces A venter på sem2
 Både A og B venter og systemet er gået i baglås.

Løsningen er, at sørge for, at de involverede processer alle tæller semaforerne ned i samme rækkefølge og tæller dem op i modsat rækkefølge.

Se også 
 Monitor – en anden synkroniseringsmulighed
 Samtidig programmering
 Parallelprogrammering

Samtidighed (datalogi)