Det finns tre nödvändiga kriterier för att deadlock ska uppstå: möjlighet till cyklisk väntan, inget återtagande av resurser och inget delande av resurser. Båda programmen uppfyller de två kriterierna om inget återtagande av resurser och inget delande av resurser men uppg3a.c uppfyller även kriteriet om möjlighet till cyklisk väntan vilket uppg3b.c inte gör.

När det uppstår deadlock i körningar av programmet uppg3a.c resulterar det i att det bara skrivs ut "en massa nollor". Detta händer aldrig vid körningar av programmet uppg3b.c eftersom deadlock inte kan uppstå utan det ger därför både ettor och nollor under hela sin livslängd. 

Den stora skillnaden mellan programmen är att trådarna som skapas i uppg3a.c använder sig av funktionen pthread_mutex_lock för att låsa mutex:arna medan trådarna i uppg3b.c använder sig av pthread_mutex_trylock.

Hur dessa funktioner fungerar beskrivs på manualsidan för pthread_mutex_lock/trylock/unlock där vi hittar följande citatat:

	"The mutex object referenced by mutex shall be locked by calling pthread_mutex_lock
	(). If the mutex is already locked, the calling thread shall block until the mutex
	becomes available. This operation shall return with the mutex object referenced by
	mutex in the locked state with the calling thread as its owner."

	"The pthread_mutex_unlock() function shall release the mutex object referenced by
	mutex."

	"The pthread_mutex_trylock() function shall be equivalent to pthread_mutex_lock(),
	except that if the mutex object referenced by mutex is currently locked (by any
	thread, including the current thread), the call shall return immediately."

Detta innebär att endast en tråd kan låsa en mutex och att det är tråden själv som kan låsa upp den igen (om en annan tråd än den som har låst den försöker låsa upp en mutex anges att det resulterar i ett fel eller odefinierat beteende). Det medför att både användandet av pthread_mutex_lock och pthread_mutex_trylock alltså uppfyller de två nödvändiga kraven för att deadlock ska uppstå rörande inget återtagande av resurser och inget delande av resurser.

Funktionerna pthread_mutex_lock och pthread_mutex_trylock skiljer sig istället åt när den anropande tråden försöker låsa en mutex som redan är låst av en annan tråd. För pthread_mutex_lock anges "If the mutex is already locked, the calling thread shall block until the mutex becomes available" vilket innebär att funktionen inte returnerar förrän den har lyckats låsa mutex:en och den anropande tråden blir blockerad under tiden. För pthread_mutex_trylock anges istället "..if the mutex object referenced by mutex is currently locked (by any thread, including the current thread), the call shall return immediately" vilket innebär att funktionen returnerar även om mutex:en är låst och tråden kan då fortsätta utföra instruktioner.

## Programmet upp3a.c ##
Eftersom trådarna t1 och t2 försöker låsa olika mutex:ar först (t1 försöker låsa m1 och t2 försöker låsa m2) och använder pthread_mutex_lock finns risken att de lyckas låsa varsinn mutex och då uppstår deadlock eftersom de väntar cykliskt på att den andre ska låsa upp sin mutex. Sannolikheten att detta ska uppstå blir ännu större eftersom de sover en sekund mellan att de låst sin första mutex och försöker låsa sin andra vilket ger den andra tråden ett längre tidsintervall till att hinna låsa sin första mutex så att deadlock då uppstår.

De körningar av programmet då trådarnas första anrop till funktionen choose på rad 16 respektive rad 27 råkar returnera samma slumptal kommer det direkt uppstå en deadlock. Då sover nämligen båda trådarna först lika länge och sen låser de varsinn mutex (t1 låser m1 och t2 låser m2). Sen sover båda 1 sekund var innan de försöker låsa den andra mutexen (t1 försöker låsa m2 och t2 försöker låsa m1) vilket misslyckas eftersom dessa då redan är låsta. Här uppstår en cyklisk väntan där t1 har låst m1 och väntar på att få låsa m2 men m2 är låst av t2 som i sin tur väntar på att få låsa m1.

På samma sätt kan trådarna när som helst under programmets körning hamna i en cyklisk väntan om deras cykler av att sova och låsa mutex:ar råkar sammanfalla på ett sådant sätt att den beskrivna cykliska väntan uppstår.

## Programmet uppg3b.c ##
Här försöker trådarna t1 och t2 också först låsa olika mutex:ar med hjälp av pthread_mutex_lock (t1 försöker låsa m1 och t2 försöker låsa m2) men eftersom pthread_mutex_trylock sedan direkt returnerar när de försöker låsa sin andra mutex (t1 försöker låsa m2 och t2 försöker låsa m1) kan trådarnas beteende styras med en if-sats beroende på om de lyckas låsa sin andra mutex och då sätter thread till sitt nummer samt sover en sekund ett slumpat antal gånger eller misslyckas att låsa sin andra mutex och då istället låser upp den mutex:en som de redan låst. Eftersom trådarna här antingen lyckas låsa båda mutex:arna eller misslyckas och då låser upp den de redan har lyckats låsa kan de inte hamna i en cyklisk väntan och därför uppstår inte deadlock.

