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.