Instantly share code, notes, and snippets.

Embed
What would you like to do?
Creating threads and dependencies using pthreads and Swift
import Foundation
import Darwin
/// Helper function to run "say" and get the Mac to talk.
func say(_ thing: String) {
let task = Process()
task.launchPath = "/usr/bin/say"
task.arguments = [thing]
task.launch()
task.waitUntilExit()
}
/// Helper function to fake process some data.
@discardableResult
func processData(_ unused: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer? {
sleep(2)
say("process data complete")
return nil
}
/// Helper function to fake log to the network.
@discardableResult
func logToNetwork(_ unused: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer? {
sleep(3)
say("log to network complete")
return nil
}
/// Helper function to fake write data to disk.
@discardableResult
func writeToDisk(_ unused: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer? {
sleep(2)
say("write to disk complete")
return nil
}
/// Helper function to show a text activity indicator
@discardableResult
func showBusyStatus(_ unused: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer? {
print("Processing... ", terminator: "")
// not actually infinite to surpress some warnings :)
for i in 1...1000000000 {
if i % 4 == 0 {
print("\u{8}/", terminator: "")
} else if i % 4 == 1 {
print("\u{8}-", terminator: "")
} else if i % 4 == 2 {
print("\u{8}\\", terminator: "")
} else if i % 4 == 3 {
print("\u{8}|", terminator: "")
}
fflush(stdout)
usleep(100000)
}
return nil
}
/// Refactored function to process data, wait, then do other things.
func doWork(_ unused: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer? {
var tProcessData: pthread_t?
pthread_create(&tProcessData, nil, processData, nil)
pthread_join(tProcessData!, nil)
// Process data is complete!!
var tLogToNetwork: pthread_t?
pthread_create(&tLogToNetwork, nil, logToNetwork, nil)
var tWriteToDisk: pthread_t?
pthread_create(&tWriteToDisk, nil, writeToDisk, nil)
pthread_join(tLogToNetwork!, nil)
pthread_join(tWriteToDisk!, nil)
return nil
}
//// Here on the "main thread"
// Thread to start our work
var tDoWork: pthread_t?
pthread_create(&tDoWork, nil, doWork, nil)
// Thread to spin the activity indicator
var tShowBusyStatus: pthread_t?
pthread_create(&tShowBusyStatus, nil, showBusyStatus, nil)
// Wait for the work to complete
pthread_join(tDoWork!, nil)
// Work is complete at this point!
// Stop the activity indicator
pthread_cancel(tShowBusyStatus!)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment