Skip to content

Instantly share code, notes, and snippets.

@mrnkr
Created October 24, 2018 01:54
Show Gist options
  • Save mrnkr/d4d687ce8e32f5a66c92002d814be0e9 to your computer and use it in GitHub Desktop.
Save mrnkr/d4d687ce8e32f5a66c92002d814be0e9 to your computer and use it in GitHub Desktop.
Producer-Consumer problem implemented in Swift using Semaphores
import UIKit
class Semaphore {
var n: Int
init(n: Int) {
self.n = n
}
func P() {
while self.n == 0 {}
self.n = self.n - 1
}
func V() {
self.n = self.n + 1
}
}
class Buffer<T> {
var buf: [T]
var top: Int
var bot: Int
var len: Int
init(capacity: Int) {
buf = []
top = 0
bot = 0
len = capacity;
}
func push(elem: T) {
buf.insert(elem, at: top)
top = (top + 1) % len
}
func pop() -> T {
let val = buf[bot]
bot = (bot + 1) % len
return val
}
}
let size: Int = 10
var mutex: Semaphore = Semaphore(n: 1) // Blocks when buffer is in use
var empty: Semaphore = Semaphore(n: 0) // Blocks when buffer is empty
var full: Semaphore = Semaphore(n: size) // Blocks when buffer is full
var buffer: Buffer<Int> = Buffer<Int>(capacity: size)
var consumed: Int = 0
func producer() {
while consumed < 50 {
let prod: Int = Int.random(in: 1 ... 10)
full.P()
mutex.P()
buffer.push(elem: prod)
mutex.V()
empty.V()
}
}
func consumer(consume: (Int) -> Void) {
while consumed < 50 {
empty.P()
mutex.P()
consume(buffer.pop())
mutex.V()
full.V()
}
}
DispatchQueue.global(qos: .userInitiated).async {
producer()
}
DispatchQueue.global(qos: .userInitiated).async {
consumer { (value: Int) in
print("Consumed \(value)")
consumed = consumed + 1
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment