bug-gnulib@gnu.org mirror (unofficial)
 help / color / mirror / Atom feed
* doc: New chapter 'Multithreading'
@ 2020-06-01 22:48 Bruno Haible
  0 siblings, 0 replies; only message in thread
From: Bruno Haible @ 2020-06-01 22:48 UTC (permalink / raw)
  To: bug-gnulib; +Cc: jemarch

[-- Attachment #1: Type: text/plain, Size: 291 bytes --]

The support for the three multithreading APIs is complete in Gnulib since
2020-01-19, except for the documentation. Let me now document it.


2020-06-01  Bruno Haible  <bruno@clisp.org>

	doc: New chapter 'Multithreading'.
	* doc/multithread.texi: New file.
	* doc/gnulib.texi: Include it.


[-- Attachment #2: 0001-doc-New-chapter-Multithreading.patch --]
[-- Type: text/x-patch, Size: 10727 bytes --]

From fb5645d8d351d5d89a9bb4b6f3f0158548924514 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Tue, 2 Jun 2020 00:37:22 +0200
Subject: [PATCH] doc: New chapter 'Multithreading'.

* doc/multithread.texi: New file.
* doc/gnulib.texi: Include it.
---
 ChangeLog            |   6 ++
 doc/gnulib.texi      |   4 +
 doc/multithread.texi | 218 +++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 228 insertions(+)
 create mode 100644 doc/multithread.texi

diff --git a/ChangeLog b/ChangeLog
index 94baf96..381ca88 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2020-06-01  Bruno Haible  <bruno@clisp.org>
 
+	doc: New chapter 'Multithreading'.
+	* doc/multithread.texi: New file.
+	* doc/gnulib.texi: Include it.
+
+2020-06-01  Bruno Haible  <bruno@clisp.org>
+
 	doc: Move 'Running self-tests under valgrind' section.
 	* doc/gnulib.texi (Build Infrastructure Modules): Include
 	valgrind-tests.texi here...
diff --git a/doc/gnulib.texi b/doc/gnulib.texi
index 68a81dc..ec6e633 100644
--- a/doc/gnulib.texi
+++ b/doc/gnulib.texi
@@ -71,6 +71,7 @@ Documentation License''.
 * Glibc Header File Substitutes::   Overriding system headers.
 * Glibc Function Substitutes::      Replacing system functions.
 * Native Windows Support::          Support for the native Windows platforms.
+* Multithreading::                  Multiple threads of execution.
 * Particular Modules::              Documentation of individual modules.
 * Regular expressions::             The regex module.
 * Build Infrastructure Modules::    Modules that extend the GNU Build System.
@@ -6649,6 +6650,9 @@ to POSIX that it can be treated like any other Unix-like platform.
 @include ld-output-def.texi
 
 
+@include multithread.texi
+
+
 @node Particular Modules
 @chapter Particular Modules
 
diff --git a/doc/multithread.texi b/doc/multithread.texi
new file mode 100644
index 0000000..b600517
--- /dev/null
+++ b/doc/multithread.texi
@@ -0,0 +1,218 @@
+@node Multithreading
+@chapter Multithreading
+
+Multithreading is a programming paradigm.  In a multithreaded program,
+multiple threads execute concurrently (or quasi concurrently) at different
+places in the program.
+
+There are three motivations for using multithreading in a program:
+@itemize @bullet
+@item
+Exploiting CPU hardware with multiple execution units.  Nowadays, many CPUs
+have 2 to 8 execution cores in a single chip.  Additionally, often multiple
+CPU chips are combined in a single package.  Thus, some CPU packages support
+64 or 96 simultaneous threads of execution.
+@item
+Simplifying program architecture.  When a program has to read from different
+file descriptors, network sockets, or event channels at the same time, the
+classical single-threaded architecture is to have a main loop which uses
+@code{select} or @code{poll} on all the descriptors and then dispatches
+according to from which descriptor input arrived.  In a multi-threaded
+program, you allocate one thread for each descriptor, and these threads can
+be programmed and managed independently.
+@item
+Offloading work from signal handlers.  A signal handler is not allowed to
+call @code{malloc}; therefore you are very limited in what you can do in
+a signal handler.  But a signal handler can notify a thread, and the thread
+can then do the appropriate processing, as complex as it needs to be.
+@end itemize
+
+A multithreading API offers
+@itemize @bullet
+@item
+Primitives for creating threads, for waiting until threads are terminated,
+and for reaping their results.
+@item
+Primitives through which different threads can operate on the same data or
+use some data structures for communicating between the threads.  These are
+called ``mutexes'' or ``locks''.
+@item
+Primitives for executing a certain (initialization) code at most once.
+@item
+Primitives for notifying one or more other threads.  These are called wait
+queues or ``condition variables''.
+@item
+Primitives for allowing different threads to have different values for a
+variable.  Such a variable is said to reside in ``thread-local storage'' or
+``thread-specific storage''.
+@item
+Primitives for relinquishing control for some time and letting other threads
+go.
+@end itemize
+
+Note: Programs that achieve multithreading through OpenMP (cf. the gnulib
+module @samp{openmp}) don't create and manage their threads themselves.
+Nevertheless, they need to use mutexes/locks in many cases.
+
+@menu
+* Multithreading APIs::
+* Choosing a multithreading API::
+* POSIX multithreading::
+* ISO C multithreading::
+* Gnulib multithreading::
+@end menu
+
+@node Multithreading APIs
+@section The three multithreading APIs
+
+Three multithreading APIs are available to Gnulib users:
+@itemize @bullet
+@item
+POSIX multithreading,
+@item
+ISO C multithreading,
+@item
+Gnulib multithreading.
+@end itemize
+
+They are supported on all platforms that have multithreading in one form or
+the other.  Currently, these are all platforms supported by Gnulib, except
+for Minix.
+
+The main differences are:
+@itemize @bullet
+@item
+The exit code of a thread is a pointer in the POSIX and Gnulib APIs, but
+only an @code{int} in the ISO C API.
+@item
+The POSIX API has additional facilities for detaching threads, setting the
+priority of a thread, assigning a thread to a certain set of processors,
+and much more.
+@item
+In the POSIX and ISO C APIs, most functions have a return code, and you
+are supposed to check the return code; even locking and unlocking a lock
+can fail.  In the Gnulib API, many functions don't have a return code; if
+they cannot complete, the program aborts.  This sounds harsh, but such
+aborts have not been reported in 12 years.
+@item
+In the ISO C API, the initialization of a statically allocated lock is
+clumsy: You have to initialize it through a once-only function.
+@end itemize
+
+@node Choosing a multithreading API
+@section Choosing the right multithreading API
+
+Here are guidelines for determining which multithreading API is best for
+your code.
+
+In programs that use advanced POSIX APIs, such as spin locks,
+detached threads (@code{pthread_detach}),
+signal blocking (@code{pthread_sigmask}),
+priorities (@code{pthread_setschedparam}),
+processor affinity (@code{pthread_setaffinity_np}), it is best to use
+the POSIX API.  This is because you cannot convert an ISO C @code{thrd_t}
+or a Gnulib @code{gl_thread_t} to a POSIX @code{pthread_t}.
+
+In code that is shared with glibc, it is best to use the POSIX API as well.
+
+In libraries, it is best to use the Gnulib API.  This is because it gives
+the person who builds the library an option
+@samp{--enable-threads=@{isoc,posix,windows@}}, that determines on which
+native multithreading API of the platform to rely.  In other words, with
+this choice, you can minimize the amount of glue code that your library
+needs to contain.
+
+In the other cases, the POSIX API and the Gnulib API are equally well suited.
+
+The ISO C API is never the best choice, as of this writing (2020).
+
+@node POSIX multithreading
+@section The POSIX multithreading API
+
+The POSIX multithreading API is documented in POSIX
+@url{https://pubs.opengroup.org/onlinepubs/9699919799/}.
+
+To make use of POSIX multithreading, even on platforms that don't support it
+natively (most prominently, native Windows), use the following Gnulib modules:
+@multitable @columnfractions .75 .25
+@headitem Purpose @tab Module
+@item For thread creation and management:@tie{} @tab @code{pthread-thread}
+@item For simple and recursive locks:@tie{} @tab @code{pthread-mutex}
+@item For read-write locks:@tie{} @tab @code{pthread-rwlock}
+@item For once-only execution:@tie{} @tab @code{pthread-once}
+@item For ``condition variables'' (wait queues):@tie{} @tab @code{pthread-cond}
+@item For thread-local storage:@tie{} @tab @code{pthread-tss}
+@item For relinquishing control:@tie{} @tab @code{sched_yield}
+@item For spin locks:@tie{} @tab @code{pthread-spin}
+@end multitable
+
+There is also a convenience module named @code{pthread} which depends on all
+of these (except @code{sched_yield}); so you don't need to enumerate these
+modules one by one.
+
+@node ISO C multithreading
+@section The ISO C multithreading API
+
+The ISO C multithreading API is documented in ISO C 11
+@url{http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf}.
+
+To make use of ISO C multithreading, even on platforms that don't support it
+or have severe bugs, use the following Gnulib modules:
+@multitable @columnfractions .85 .15
+@headitem Purpose @tab Module
+@item For thread creation and management:@tie{} @tab @code{thrd}
+@item For simple locks, recursive locks, and read-write locks:@tie{}
+      @tab @code{mtx}
+@item For once-only execution:@tie{} @tab @code{mtx}
+@item For ``condition variables'' (wait queues):@tie{} @tab @code{cnd}
+@item For thread-local storage:@tie{} @tab @code{tss}
+@end multitable
+
+There is also a convenience module named @code{threads} which depends on all
+of these; so you don't need to enumerate these modules one by one.
+
+@node Gnulib multithreading
+@section The Gnulib multithreading API
+
+The Gnulib multithreading API is documented in the respective include files:
+@itemize
+@item
+@code{<glthread/thread.h>}
+@item
+@code{<glthread/lock.h>}
+@item
+@code{<glthread/cond.h>}
+@item
+@code{<glthread/tls.h>}
+@item
+@code{<glthread/yield.h>}
+@end itemize
+
+To make use of Gnulib multithreading, use the following Gnulib modules:
+@multitable @columnfractions .85 .15
+@headitem Purpose @tab Module
+@item For thread creation and management:@tie{} @tab @code{thread}
+@item For simple locks, recursive locks, and read-write locks:@tie{}
+      @tab @code{lock}
+@item For once-only execution:@tie{} @tab @code{lock}
+@item For ``condition variables'' (wait queues):@tie{} @tab @code{cond}
+@item For thread-local storage:@tie{} @tab @code{tls}
+@item For relinquishing control:@tie{} @tab @code{yield}
+@end multitable
+
+The Gnulib multithreading supports a configure option
+@samp{--enable-threads=@{isoc,posix,windows@}}, that chooses the underlying
+thread implementation.  Currently (2020):
+@itemize @bullet
+@item
+@code{--enable-threads=posix} is supported and is the best choice on all
+platforms except for native Windows.  It may also work, to a limited extent,
+on mingw with the @code{winpthreads} library, but is not recommended there.
+@item
+@code{--enable-threads=windows} is supported and is the best choice on
+native Windows platforms (mingw and MSVC).
+@item
+@code{--enable-threads=isoc} is supported on all platforms that have the
+ISO C multithreading API.  However, @code{--enable-threads=posix} is always
+a better choice.
+@end itemize
-- 
2.7.4


[-- Attachment #3: Multithreading.html --]
[-- Type: text/html, Size: 16930 bytes --]

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2020-06-01 22:49 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-01 22:48 doc: New chapter 'Multithreading' Bruno Haible

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).