All Projects → typelift → Concurrent

typelift / Concurrent

Functional Concurrency Primitives

Programming Languages

swift
15916 projects

Projects that are alternatives of or similar to Concurrent

async
Synchronization and asynchronous computation package for Go
Stars: ✭ 104 (-49.51%)
Mutual labels:  synchronization, concurrency, lock
TAOMP
《多处理器编程的艺术》一书中的示例代码实现,带有注释与单元测试
Stars: ✭ 39 (-81.07%)
Mutual labels:  synchronization, concurrency, lock
Java Concurrency Examples
Java Concurrency/Multithreading Tutorial with Examples for Dummies
Stars: ✭ 173 (-16.02%)
Mutual labels:  concurrency, lock, synchronization
django-concurrency-talk
🎭 Database Integrity in Django: Safely Handling Critical Data in Distributed Systems
Stars: ✭ 49 (-76.21%)
Mutual labels:  concurrency, lock
Linux-Kernel-Driver-Programming
Implementation of PCI drivers, kprobe, sysfs, devfs, sensor driver, miscdevices, synchronization
Stars: ✭ 43 (-79.13%)
Mutual labels:  synchronization, concurrency
linked-blocking-multi-queue
A concurrent collection that extends the existing Java concurrent collection library, offering an optionally-bounded blocking "multi-queue" based on linked nodes.
Stars: ✭ 41 (-80.1%)
Mutual labels:  synchronization, concurrency
optimistic lock coupling rs
🍋: A General Lock following paper "Optimistic Lock Coupling: A Scalable and Efficient General-Purpose Synchronization Method"
Stars: ✭ 21 (-89.81%)
Mutual labels:  concurrency, lock
haxe-concurrent
A haxelib for basic platform-agnostic concurrency support
Stars: ✭ 69 (-66.5%)
Mutual labels:  concurrency, lock
aiorwlock
Read/Write Lock - synchronization primitive for asyncio
Stars: ✭ 90 (-56.31%)
Mutual labels:  concurrency, lock
AtomicKit
Concurrency made simple in Swift.
Stars: ✭ 88 (-57.28%)
Mutual labels:  concurrency, lock
syncs
Concurrency and synchronization primitives
Stars: ✭ 81 (-60.68%)
Mutual labels:  synchronization, concurrency
futex
File-based Ruby Mutex
Stars: ✭ 14 (-93.2%)
Mutual labels:  concurrency, lock
Crossbeam
Tools for concurrent programming in Rust
Stars: ✭ 4,180 (+1929.13%)
Mutual labels:  concurrency, synchronization
Mt
tlock, RWMUTEX, Collab, USM, RSem and other C++ templates for Windows to provide read/write mutex locks, various multithreading tools, collaboration, differential updates and more
Stars: ✭ 18 (-91.26%)
Mutual labels:  concurrency, lock
Mayhem
The Python asyncio tutorial I wish existed earlier
Stars: ✭ 184 (-10.68%)
Mutual labels:  concurrency
Pond
Minimalistic and High-performance goroutine worker pool written in Go
Stars: ✭ 187 (-9.22%)
Mutual labels:  concurrency
Ninja Mutex
Mutex implementation for PHP
Stars: ✭ 180 (-12.62%)
Mutual labels:  lock
React Focus On
🎯 Solution for WAI ARIA compatible modal dialogs or full-screen tasks, you were looking for
Stars: ✭ 180 (-12.62%)
Mutual labels:  lock
Zio Saga
Purely Functional Transaction Management In Scala With ZIO
Stars: ✭ 200 (-2.91%)
Mutual labels:  concurrency
Concurrent Map
a thread-safe concurrent map for go
Stars: ✭ 2,627 (+1175.24%)
Mutual labels:  concurrency

Build Status

Concurrent

Concurrent is a collection of functional concurrency primitives inspired by Concurrent ML and Concurrent Haskell. Traditional approaches to concurrency like locks, latches, and semaphores all fall under the same category of basic resource protection. While this affords them a large measure of simplicity, their use is entirely ad-hoc, and failing to properly lock or unlock critical sections can lead a program to beachball or worse. In addition, though we have become accustomed to performing work on background threads, communication between these threads is frought with peril.

The primitives in this library instead focus on merging data with protection, choosing to abstract away the use of locks entirely. By approaching concurrency from the data side, rather than the code side, thread-safety, synchronization, and protection become inherent in types rather than in code.

Take this simple example:

import struct Concurrent.Chan

/// A Channel is an unbounded FIFO stream of values with special semantics
/// for reads and writes.
let chan = Chan<Int>()

/// All writes to the Channel always succeed.  The Channel now contains `1`.
chan.write(1) // happens immediately

/// Reads to non-empty Channels occur immediately.  The Channel is now empty.
let x1 = chan.read()

/// But if we read from an empty Channel the read blocks until we write to the Channel again.
DispatchQueue.global().asyncAfter(deadline: .now() + .seconds(1)) {
  chan.write(2) // Causes the read to suceed and unblocks the reading thread.
}

let x2 = chan.read() // Blocks until the dispatch block is executed and the Channel becomes non-empty.

Unlike lock-based protection mechanisms, we can wrap mutable variables that must be accessed concurrently in an MVar.

import class Concurrent.MVar

/// An MVar (Mutable Variable) is a thread-safe synchronizing variable that can be used for
/// communication between threads.
///
/// This MVar is currently empty.  Any reads or writes to it will block until it becomes "full".
let counter : MVar<Int> = MVar()

/// Attempt to increment the counter from 3 different threads.  Because the counter is empty,
/// all of these writes will block until a value is put into the MVar.
DispatchQueue.global().async {
  counter.modify_ { $0 + 1 }
  print("Modifier #1")
}
DispatchQueue.global().async {
  counter.modify_ { $0 + 1 }
  print("Modifier #2")
}
DispatchQueue.global().async {
  counter.modify_ { $0 + 1 }
  print("Modifier #3")
}

/// All the writes will now proceed and unblock each thread in turn.  The order of writes
/// is determined by the order in which each thread called `modify(_ :)`.
counter.put(0)

// > "Modifier #1"
// > "Modifier #3"
// > "Modifier #2"

/// Empties the MVar.  If we just wanted the value without emptying it, we would use
/// `read()` instead.
///
/// Because our take occured after the put, all of the modifications we made before will
/// complete before we read the final value.
print(counter.take()) // 3

MVars can also be used purely as a synchronization point between multiple threads:

import class Concurrent.MVar

let pingvar : MVar<String> = MVar()
let pongvar : MVar<String> = MVar()
let done = MVar<()>() // The synchronization point

/// Puts a value into the now-empty ping variable then blocks waiting for the
/// pong variable to have a value put into it.  Once we have read the pong variable,
/// we unblock the done MVar, and in doing so, unblock the main thread.
DispatchQueue.global().async {
  pingvar.put("ping")
  _ = pongvar.take()
  done.put(())
}

/// Takes the contents of the ping variable then puts a value into the pong variable
/// to unblock the take we just performed.
DispatchQueue.global().async {
  _ = pingvar.take()
  pongvar.put("pong")
}

/// Blocks until all work has completed.
done.take()

Concurrent also exposes a structure for Software Transactional Memory for safe and structured access to shared memory:

typealias Account = TVar<UInt>

/// Some atomic operations
func withdraw(from account : Account, amount : UInt) -> STM<()> { 
  return account.read().flatMap { balance in
    if balance > amount {
      return account.write(balance - amount)
    }
    throw TransactionError.insufficientFunds
  } 
}

func deposit(into account : Account, amount : UInt) -> STM<()> { 
  return account.read().flatMap { balance in
    return account.write(balance + amount)
  }
}

func transfer(from : Account, to : Account, amount : UInt) -> STM<()> { 
  return from.read().flatMap { fromBalance in
    if fromBalance > amount {
      return withdraw(from: from, amount: amount)
          .then(deposit(into: to, amount: amount))
    }
    throw TransactionError.insufficientFunds
  }
}

/// Here are some bank accounts represented as TVars - transactional memory
/// variables.
let alice = Account(200)
let bob = Account(100)

/// All account activity that will be applied in one contiguous transaction.
/// Either all of the effects of this transaction apply to the accounts or
/// everything is completely rolled back and it was as if nothing ever happened.
let finalStatement = 
    transfer(from: alice, to: bob, amount: 100)
        .then(transfer(from: bob, to: alice, amount: 20))
        .then(deposit(into: bob, amount: 1000))
        .then(transfer(from: bob, to: alice, amount: 500))
        .atomically()

System Requirements

Concurrent supports OS X 10.9+ and iOS 7.0+.

Installation

Swift Package Manager

  • Add Concurrent to your Package.swift file's dependencies section:
.package(url: "https://github.com/typelift/Concurrent.git", "0.4.0"..<"1.0.0")

Carthage

Create a Cartfile that lists the framework and run carthage bootstrap. Follow the instructions to add $(SRCROOT)/Carthage/Build/iOS/Concurrent.framework to an iOS project.

github "typelift/Concurrent"

Manually

  1. Download and drop /Sources folder in your project.
  2. Congratulations!

Framework

  • Drag Concurrent.xcodeproj or Concurrent-iOS.xcodeproj into your project tree as a subproject
  • Under your project's Build Phases, expand Target Dependencies
  • Click the + and add Concurrent
  • Expand the Link Binary With Libraries phase
  • Click the + and add Concurrent
  • Click the + at the top left corner to add a Copy Files build phase
  • Set the directory to Frameworks
  • Click the + and add Concurrent

License

Concurrent is released under the MIT license.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].