Skip to content

Instantly share code, notes, and snippets.

@guarani
Last active December 29, 2021 09:22
Show Gist options
  • Save guarani/1ae275836cde77dfd87213f902b0ab17 to your computer and use it in GitHub Desktop.
Save guarani/1ae275836cde77dfd87213f902b0ab17 to your computer and use it in GitHub Desktop.
Dining Philosophers Problem in Swift with NSOperationQueue
//
// A Swift implementation of the Dining Philosophers Problem:
// https://en.wikipedia.org/wiki/Dining_philosophers_problem
//
//
// P0
// f3 f0
// P3 P1
// f2 f1
// P2
//
//
// Sample output:
//
// Starting philosoper 0
// Starting philosoper 1
// Starting philosoper 2
// Starting philosoper 3
// Philosopher 0 eating with forks 0 and 3
// Philosopher 2 eating with forks 1 and 2
// Philosopher 1 eating with forks 0 and 1
// Philosopher 3 eating with forks 2 and 3
// Philosopher 0 eating with forks 0 and 3
// Philosopher 2 eating with forks 1 and 2
// Philosopher 1 eating with forks 0 and 1
// Philosopher 3 eating with forks 2 and 3
//
// And so on...
import UIKit
import XCPlayground
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
var numPhilosophers = 4
class Fork {
let index: Int
let lock = NSLock()
init(_ index: Int) {
self.index = index
}
func pickUp(philosopher: Philosopher) {
lock.lock()
}
func putDown() {
lock.unlock()
}
}
class Philosopher {
let index: Int
var firstFork: Fork?
var secondFork: Fork?
var operation: NSBlockOperation!
init(_ index: Int) {
self.index = index
}
var leftForkIndex: Int {
return index
}
var rightForkIndex: Int {
return index == 0 ? numPhilosophers - 1 : index - 1
}
func run() {
print("Starting philosoper \(index)")
while (true) {
firstFork = forks[min(leftForkIndex, rightForkIndex)]
secondFork = forks[max(leftForkIndex, rightForkIndex)]
firstFork!.pickUp(self)
secondFork!.pickUp(self)
print("Philosopher \(index) eating with forks \(firstFork!.index) and \(secondFork!.index)")
sleep(1)
firstFork!.putDown()
secondFork!.putDown()
}
}
}
var forks = [Fork]()
var philosophers = [Philosopher]()
for i in 0 ..< numPhilosophers {
forks.append(Fork(i))
philosophers.append(Philosopher(i))
}
let queue = NSOperationQueue()
philosophers.forEach { philosopher in
philosopher.operation = NSBlockOperation() {
philosopher.run()
}
queue.addOperation(philosopher.operation)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment