Showing posts with label concurrency. Show all posts
Showing posts with label concurrency. Show all posts

Thursday, April 12, 2012

Awaitable Queues Part 2: Unbounded Awaitable Queue

As a first attempt to write an awaitable queue, the queue is unbounded. The producer side of the queue is then synchronous and we can concentrate on making consumer side awaitable. The code for the can be found at the end of this post.

Wednesday, April 11, 2012

Awaitable Queues Part 1: API

This is an experiment to see how an efficient asynchronous queue could be implemented. The natural way to implement an asynchronous queue would be using Tasks. But using Task objects can be wasteful as this would mean one or two Task & TaskCompletionSource objects allocations per queued element. Allocations are fast, but that is only because payment for allocations is done down the line when the garbage collector needs to collect the objects.

The await keyword of c# can be applied to any object (not only Tasks), and because these objects can be reused it should be possible to build a less wasteful version of an asynchronous queue.

Thursday, February 16, 2012

Locking Style for Concurrent Programs (c#)

As a job I do a lot of asynchronous programming. I have been working intensively with multi threading some 6 years now (before that I did programming on Unix in c++).

As a consequence of the problems I encountered during this 6 year period, the way I use locks has changed a lot. The most recurring problems were:
  • deadlocks.
  • pumping on the UI thread. When the UI-thread waits on a lock, the runtime can decide to start pumping on that call stack!!! This way *any* code can be called from nearly any point in your code. This can easily cause deadlocks or other (crazy) faulty programs because of unexpected reentry.
  • performance: I used to take my locks over longer periods of time. For example during doing I/O or remoting to get some kind of serialization behavior. Instead it has shown to be a better idea to schedule work where possible, as it is often not important when something really happens.
I adopted a certain style when writing code with locks, in effect limiting the way in which locks are used. They are now used only to protect against concurrent access of fields and possibly to order the task scheduling. This style forces me to use other (higher level) constructs for coordination. This style has served me well in writing cleaner concurrent code.