Threads

Threads provide a means of representing multiple parallel execution contexts. NNG makes use of this concept internally, but also provides for user applications to utilize the same thread facilities. This allows one form of concurrency for applications.

note

Threads in NNG are built upon platform support, which may be based upon operating system supplied threads, process, or coroutines. The appearance of concurrency does not guarantee true concurrency, and scheduling between threads may not necessarily be pre-emptive. While this will not adversely impact applications that use this facility for I/O bound concurrency, it may not provide good results for purely CPU-bound operations.

important

Thread objects created by this function may not be real system-level threads capable of performing blocking I/O operations using normal blocking system calls. If use of blocking system calls is required (not including APIs provided by the NNG library itself of course), then real OS-specific threads should be created instead (such as with pthread_create or similar functions.) Blocking NNG library calls can however be made safely from NNG threads.

tip

The system may impose limits on the number of threads that can be created. Typically applications should not create more than a dozen of these. If greater concurrency or scalability is needed, consider instead using an asynchronous model using nng_aio structures.

Thread Structure

typedef struct nng_thread nng_thread;

The nng_thread structure represnts a thread, which is a single execution context. A given thread will have its own stack, and CPU registers. However global state, as well as values allocated on the heap, will be shared and accessible to all threads in the system (See the Synchronization chapter for functions to help with data sharing between different threads.)

Multiple threads can be thought of as running concurrently, even though they might not actually do so.

I/O operations that block (i.e. wait for completion) will block the thread, while allowing other threads to proceed.

Creating a Thread

int nng_thread_create(nng_thread **thrp, void (*func)(void *), void *arg);

The nng_thread_create function creates a thread, which will execute func, with the given argument arg, and returns a pointer to it in thrp.

The thread may begin execution immediately.

The thread will persist until func returns.

This function returns zero on success, but may return NNG_ENOMEM if insufficient resources to create a thread are available.

Destroying a Thread

void nng_thread_destroy(nng_thread *thr);

The nng_thread_destroy function waits for the thread thr to finish execution. This function should be called to reclaim any resources associated with the thread when done. It also has the effect of blocking execution in the caller until thr has completed executing.

Thread Names

void nng_thread_set_name(nng_thread *thr, const char *name);

In order to facilitate debugging, nng_thread_set_name may be called to provide a name for the thread. This may change how the thread is represented in debuggers. Not all platforms support setting the thread name.

See Also

Synchronization, Asynchronous Operations