Last active
December 29, 2021 09:22
-
-
Save guarani/1ae275836cde77dfd87213f902b0ab17 to your computer and use it in GitHub Desktop.
Dining Philosophers Problem in Swift with NSOperationQueue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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