Programming: Threads

From wikinotes

Threads are units of synchronous code that can be multiplexed within a process.
Threads belonging to the same process, and share the same memory, so care needs to be taken to ensure the same object is not changed twice.

Documentation

wikipedia: thread https://en.wikipedia.org/wiki/Thread_(computing)


Components

Basics

Threads each have their own:

  • stack
  • registers
  • thread locals

Threads share with their parent-process (and other threads in the same process)

  • heap

Affinity

Threads can be pinned to a CPU core, the core they are bound to is their affinity.
Some systems (like Qt) may let you pin a created object to a different cpu-core, changing the object's thread affinity.

Thread Safety

Strategies

Thread safety can be achieved by

  • confinement not sharing state across threads
  • message-passing communicating only sharing immutable or duplicated state through a message queue
  • synchronization coordinates shared memory between threads

Atomicity

When an operation occurs on a resource in a concurrent system,
it is considered atomic when access to the item is blocked while it is being modified.
It should not be read, or mutated while it is undergoing mutation.

the following are particularly prone to atomicity issues:

  • memoization/late binding (ex. package attributes)
  • read-then-write operations
  • modifying multiple related variables (atomic individually or not)

intrinsic locks are one solution for this.
blocks of code executed while a lock is acquired, like a database transaction,
or Qt's mutexes that are allocated on the stack, and released on object destruction.

Shared Memory

When sharing memory, you need to be careful that

  • the value is not only partially written
  • the value is not changed while it is being used

Synchronized Primitives

Some languages may provide safer ways of sharing memory.

  • atomic types generally guarantee a read/write to it's value is protected
  • volatile types generally ensure the value is up to date between threads (no caching). but does not protect getting/setting the variable.

Strategies

  • Confined to thread (thread/object local)
  • Shared/Read-Only (constants never written to)
  • Synchronized accessed with internally or externally managed locks
  • Wrapping/Accessing unsafe code from a synchronized interface