I have one that I created for Swift on OS X which uses libdispatch to protect
access to the underlying data:
/* dictionary that allows thread safe concurrent access */
final class ConcurrentDictionary<KeyType:Hashable,ValueType> : NSObject,
SequenceType, DictionaryLiteralConvertible {
/* internal dictionary */
private var internalDictionary : [KeyType:ValueType]
/* queue modfications using a barrier and allow concurrent read operations */
private let queue = dispatch_queue_create( "dictionary access",
DISPATCH_QUEUE_CONCURRENT )
/* count of key-value pairs in this dicitionary */
var count : Int {
var count = 0
dispatch_sync(self.queue) { () -> Void in
count = self.internalDictionary.count
}
return count
}
// safely get or set a copy of the internal dictionary value
var dictionary : [KeyType:ValueType] {
get {
var dictionaryCopy : [KeyType:ValueType]?
dispatch_sync(self.queue) { () -> Void in
dictionaryCopy = self.dictionary
}
return dictionaryCopy!
}
set {
let dictionaryCopy = newValue // create a local copy on the current thread
dispatch_async(self.queue) { () -> Void in
self.internalDictionary = dictionaryCopy
}
}
}
/* initialize an empty dictionary */
override convenience init() {
self.init( dictionary: [KeyType:ValueType]() )
}
/* allow a concurrent dictionary to be initialized using a dictionary literal
of form: [key1:value1, key2:value2, ...] */
convenience required init(dictionaryLiteral elements: (KeyType, ValueType)...) {
var dictionary = Dictionary<KeyType,ValueType>()
for (key,value) in elements {
dictionary[key] = value
}
self.init(dictionary: dictionary)
}
/* initialize a concurrent dictionary from a copy of a standard dictionary */
init( dictionary: [KeyType:ValueType] ) {
self.internalDictionary = dictionary
}
/* provide subscript accessors */
subscript(key: KeyType) -> ValueType? {
get {
var value : ValueType?
dispatch_sync(self.queue) { () -> Void in
value = self.internalDictionary[key]
}
return value
}
set {
setValue(newValue, forKey: key)
}
}
/* assign the specified value to the specified key */
func setValue(value: ValueType?, forKey key: KeyType) {
// need to synchronize writes for consistent modifications
dispatch_barrier_async(self.queue) { () -> Void in
self.internalDictionary[key] = value
}
}
/* remove the value associated with the specified key and return its value if
any */
func removeValueForKey(key: KeyType) -> ValueType? {
var oldValue : ValueType? = nil
// need to synchronize removal for consistent modifications
dispatch_barrier_sync(self.queue) { () -> Void in
oldValue = self.internalDictionary.removeValueForKey(key)
}
return oldValue
}
/* Generator of key-value pairs suitable for for-in loops */
func generate() -> Dictionary<KeyType,ValueType>.Generator {
var generator : Dictionary<KeyType,ValueType>.Generator!
dispatch_sync(self.queue) { () -> Void in
generator = self.internalDictionary.generate()
}
return generator
}
}
_____________________________________________________________________________________
Thomas Pelaia II, Ph.D. | Applications Leader, Accelerator Physics, Research
Accelerator Division
Spallation Neutron Source | Oak Ridge National Lab, Building 8600, MS-6462,
Oak Ridge, TN 37831
phone: (865) 414-7960 | FaceTime: [email protected]<mailto:[email protected]> | fax:
(865) 574-6617 | homepage: http://www.ornl.gov/~t6p
On Dec 10, 2015, at 12:18 PM, swift-users
<[email protected]<mailto:[email protected]>> wrote:
Hi,
I'm writing some code where I'd like multiple threads to be writing to a common
dictionary object.
Is there a recommended mechanism for doing this?
Thanks,
Lane
_______________________________________________
swift-users mailing list
[email protected]<mailto:[email protected]>
https://lists.swift.org/mailman/listinfo/swift-users
_______________________________________________
swift-users mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-users