Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/tidwall/Safe
Modern Concurrency and Synchronization for Swift.
https://github.com/tidwall/Safe
Last synced: about 1 month ago
JSON representation
Modern Concurrency and Synchronization for Swift.
- Host: GitHub
- URL: https://github.com/tidwall/Safe
- Owner: tidwall
- License: mit
- Archived: true
- Created: 2015-06-30T21:23:33.000Z (over 9 years ago)
- Default Branch: master
- Last Pushed: 2019-06-18T23:55:52.000Z (over 5 years ago)
- Last Synced: 2024-03-14T18:34:57.162Z (9 months ago)
- Language: Swift
- Homepage:
- Size: 542 KB
- Stars: 417
- Watchers: 16
- Forks: 26
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-swift-cn - Safe - A modern concurrency and synchronization for Swift. (Libs / Events)
- awesome-github-repos - tidwall/Safe - Modern Concurrency and Synchronization for Swift. (Swift)
README
##Features
- Simple `Atomic` class for numbers and strings.
- Uncomplicated `dispatch` keyword for firing off background routines.
- Awesome `Chan` for concurrent communication.
- Useful sync APIs. `Mutex`, `Cond`, `Once`, `WaitGroup`## Atomic
#### Types
`Int`, `Int8`, `Int16`, `Int32`, `Int64`, `UInt`, `UInt8`, `UInt16`, `UInt32`, `UInt64`, `Float`, `Double`, `Bool`, `String`#### Operators
`==`, `!=`, `&&`, `||`, `<=`, `>=`, `>`, `<`, `!`
`+`, `-`, `*`, `/`, `%`, `<<`, `>>`, `^`, `&`, `&+`, `&-`, `&*`, `++`, `--`, `+=`, `-=`, `*=`, `/=`, `%=`, `+=`, `<<=`, `>>=`, `^=`, `&=````swift
var anum = IntA(100) // IntA is an alias for Atomic.
anum += 15 // Adds a value atomically.
let res = anum % 4 // Modulo operation atomically.
print("\(anum) \(res)") // prints '115 3'.
```## Dispatch
Safe adds an uncomplicated method for dispatching routines.
```swift
dispatch {
print("Background")
}
print("Foreground")
```## Channels
A new `Chan` class provides a clean and simple model for concurrently sharing objects. `Chan` is modeled after [Go channels](https://golang.org/doc/effective_go.html#channels).
[Sharing Memory by Communicating](http://blog.golang.org/share-memory-by-communicating)
#### Example
```swift
let jobs = Chan(5) // buffered channel
let done = Chan() // unbuffered channeldispatch {
for ;; {
if let j = <-jobs {
print("received job \(j)")
} else {
print("received all jobs")
done <- true
return
}
}
}for var j = 1; j <= 3; j++ {
jobs <- j
print("sent job \(j)")
}
jobs.close()
print("sent all jobs")<-done
```#### Iterate
A channel can also be iterated through.
```swift
while let j = <-jobs {
print("received job \(j)")
}
print("received all jobs")
```#### Select
The `_select` keyword is a multiway communications multiplexer that works on multiple channels. `_select`, `_case`, and `_default` start with underscores so that they do not conflict with the `select`, `case`, and `default` syscall and keywords. *When a `_select` encounters multiple channels with data, the chosen `_case` is selected at random*
```swift
let jobs1 = Chan()
let jobs2 = Chan()dispatch {
for ;; {
_select {
_case(jobs1){ j in
print("received 1: \(j)")
}
_case(jobs2){ j in
print("received 2: \(j)")
}
}
}
}for var j = 1; ; j++ {
jobs1 <- (j * 1000)
jobs2 <- (j * 2000)
NSThread.sleepForTimeInterval(1)
}
```#### Select with Default
A `_select` can contain a single `_default` for non-blocking operations.
```swift
_select {
_case(jobs1){ j in
print("received 1: \(j)")
}
_case(jobs2){ j in
print("received 2: \(j)")
}
_default {
print("channels not ready")
}
}
```## Mutex, Cond, Once, WaitGroup
Incredibly useful sync APIs.
#### Mutex
```swift
let m = Mutex()
m.lock()
m.unlock()
m.lock {
// this block is locked
}
```
#### Cond
```swift
let c = Cond(Mutex())
c.wait() // wait for signal.
c.wait(0.25) // wait for signal or 250ms to pass.
c.signal() // signal to one wait.
c.broadcast() // signal to all waits.
```
#### Once
```swift
func f(){
print("hey there")
}let o = Once()
o.doit(f) // runs once
o.doit(f) // noop: cannot run twice
```
#### WaitGroup
```swift
let dosomething : (NSTimeInterval, WaitGroup)->() = { (delay, wg) in
NSThread.sleepForTimeInterval(delay)
print("Function in background, duration: \(delay)")
wg.done()
}
let wg = WaitGroup()
wg.add(1)
dispatch { dosomething(0.40, wg) }
wg.add(1)
dispatch { dosomething(0.30, wg) }
wg.add(1)
dispatch { dosomething(0.15, wg) }
wg.add(1)
dispatch { dosomething(0.60, wg) }
wg.wait()
print("done")
```##Installation (iOS and OS X)
### [Carthage]
[Carthage]: https://github.com/Carthage/Carthage
Add the following to your Cartfile:
```
github "tidwall/Safe"
```Then run `carthage update`.
Follow the current instructions in [Carthage's README][carthage-installation]
for up to date installation instructions.[carthage-installation]: https://github.com/Carthage/Carthage#adding-frameworks-to-an-application
The `import Safe` directive is required in order to access Safe features.
### [CocoaPods]
[CocoaPods]: http://cocoapods.org
Add the following to your [Podfile](http://guides.cocoapods.org/using/the-podfile.html):
```ruby
use_frameworks!
pod 'Safe'
```Then run `pod install` with CocoaPods 0.36 or newer.
The `import Safe` directive is required in order to access Safe features.
### [SPM]
[SPM]: https://swift.org/package-manager/
Add the following to your `Package.swift`
```swift
dependencies: [
...
.Package(url: "https://github.com/tidwall/Safe", majorVersion: 1, minor: 2)
]
```Then run `swift build`.
The `import Safe` directive is required in order to access Safe features.
### Manually
Copy the `Source/*.swift` file into your project.
There is no need for `import Safe` when manually installing.
## Contact
Josh Baker [@tidwall](http://twitter.com/tidwall)## License
The Safe source code is available under the MIT License.