Class: ThreadPool

core.ThreadPool

Class representing a scalable thread pool with means for lock-free concurrent programming.

UI Thread

The UI thread is the main thread of the application. Unless posted to a thread pool, all code is running in the UI thread. Blocking the UI thread (e.g. by computation-heavy actions) will freeze the user interface and should be avoided.

The thread pool lets you run code outside the UI thread so it doesn't get blocked.

Worker Thread

The thread pool provides a number of worker threads, depending on its size property. Worker threads accept and fulfil tasks posted to the thread pool.

There is a limit to the amount of worker threads that the computer is able to run simultaneously at the same time, which is the hardwareConcurrency. This limit depends on the CPU type.

It is, however, possible to run threads exceeding the hardwareConcurrency virtually simultaneously. To the user it would appear as if the threads would be running simultaneously, but actually, they are taking turns and the performance benefit of running simultaneously is not given.

Task

A task is a piece of code that is to be run by a worker thread. The thread pool is responsible for queueing tasks and assigning them to worker threads that are free of tasks (i.e. idle).

To run a task, you post it to the thread pool. If the task implements the function run(), it will be invoked automatically with the given parameters. Posting a task that implements run will return a Promise object for retrieving a potential task result.

const code = "funcftion run(a, b) { return a + b; }";
const task = pool.postTask(code, 1, 2)
.then(sum => {
  console.log("The result is: " + sum);
});

Normally, tasks free the worker thread after running, but if a task has exported functions, or created a proxy object, it continues to occupy the worker thread and stays ready to be called, until it terminates itself by calling the exit() function.

Exporting Functions

Tasks may export functions to be called by the UI thread. Functions are exported by assigning them to the exports namespace.

exports.sum = (a, b) => { return a + b; };

A tasks that exports functions is not terminated automatically and continues to occupy the worker thread it was assigned to.

Proxy Objects

Tasks may create proxy objects for controlling objects living in the task by the UI thread. This provides a way to implement the Active Object Pattern.

class MyActiveObject {
    // implementation goes here
    ...
}

function run()
{
    return proxyObject(new MyActiveObject());
}

A task that creates proxy objects is not terminated automatically and continues to occupy the worker thread it was assigned to.

Callback Functions

Functions may be passed between threads as callbacks. Invoking a callback guarantees that the function will be executed in the thread where it came from.

Since callback functions may be called more than once, they are not freed while the task is running. In order to free a callback function immediately, have it return true explicitly.

Atomic Integers

Atomic integers are 32bit integer values that may be shared and modified by several threads safely. Usually the CPU supports atomic operations on the values directly with no extra locking overhead.

Atomics provide a quick way to notify threads about something by raising a flag.

Transfering Data

Normally when an object is passed to a task or back to the UI thread as a function or method parameter, a copy of the object will be made for passing. This can be quite expensive for large objects.

Some types, however, support being transfered directly between threads without copying. A transfered object is no longer usable in the thread where it was transfered from.

This mechanism is comparable to the std::move() semantics of C++.

new core.ThreadPool ()

Properties:
Name Type Description
free number

[readonly] The amount of free workers.

hardwareConcurrency number

[readonly] The maximum amount of concurrent threads supported by the hardware.

pending number

[readonly] The amount of tasks that are either waiting or running.

size number

(default: 1) The size of the thread pool, i.e. the amount of available workers.

waiting number

[readonly] The amount of tasks that are waiting for a free worker.

Extends

Methods

Creates an atomic int32 for lock-free inter-thread communication. This feature may only be usable if the environment is cross origin isolated.

Name Type Description
n number

The initial value.

Returns:
Type Description
html.ThreadPool.AtomicInt32 The atomic int32.

postTask (code, parameters)html.ThreadPool.TaskHandle

Posts the given task to the next free worker thread and returns a TaskHandle object.

Transferable objects may be transfered (instead of being copied) to the worker thread by marking the parameter with transfer().

Functions may be passed as parameters to act as callbacks.

Name Type Description
code string

The code to execute.

parameters Array.<any> repeatable

The parameters.

Returns:
Type Description
html.ThreadPool.TaskHandle The TaskHandle object for retrieving the result or an exception.

postTaskFromSource (url, parameters)html.ThreadPool.TaskHandle

Posts the given task to the next free worker thread and returns a TaskHandle object.

Name Type Description
url string

The URL of the task to load.

parameters Array.<any> repeatable

The parameters.

Returns:
Type Description
html.ThreadPool.TaskHandle The TaskHandle object for retrieving the result or an exception.

transfer (obj)Transferable

Marks the given transferable object for transfer instead of copying.

So far, HTML5 recognizes ArrayBuffer, CanvasProxy, ImageBitmap, and MessagePort as transferable.

Name Type Description
obj Transferable

The object to mark for transfer.

Returns:
Type Description
Transferable The object to transfer.