Académique Documents
Professionnel Documents
Culture Documents
WIN32 THREADS
A Case Study on the Similarities and Differences between
POSIX threads in UNIX and WIN32 threads in Windows.
CONOR KELLEHER
JACK BEEGAN
OISN KYNE
13395381
13397866
13398651
Contents
Who Wrote What? .................................................................................................................................. 2
Introduction ............................................................................................................................................ 3
Win32 Threads in Windows .................................................................................................................... 4
History ................................................................................................................................................. 4
Threads ............................................................................................................................................... 4
Thread Creation .................................................................................................................................. 4
Thread Interaction .............................................................................................................................. 5
Thread Destruction ............................................................................................................................. 5
POSIX Threads in UNIX ............................................................................................................................ 6
History ................................................................................................................................................. 6
Threads ............................................................................................................................................... 6
Thread Creation .................................................................................................................................. 6
Thread Interaction .............................................................................................................................. 7
Thread Termination ............................................................................................................................ 7
Win32 Threads and POSIX Threads Comparison .................................................................................... 9
Overview ............................................................................................................................................. 9
Modern Usage and Popularity ............................................................................................................ 9
Thread Creation .................................................................................................................................. 9
Thread Interaction ............................................................................................................................ 10
Thread Termination .......................................................................................................................... 10
Conclusions ........................................................................................................................................... 11
References ............................................................................................................................................ 12
1|Page
2|Page
Research
o Initial topic exploration
o POSIX threads
History
Implementation
o WIN32 threads
History
Implementation
Document
o Introduction
o Thread Overview - Windows
History
Threads
Thread Creation
Thread Interaction
Thread Termination
o Thread Overview - POSIX
History
Threads
Thread Creation
Thread Interaction
Thread Termination
o Thread Comparisons
Overview
Popularity & Modern Use
Thread Creation
Thread Interaction
Thread Termination
o Discussion & Conclusions
o References
Proof Reading & Editing
Conor Kelleher
Jack Beegan
Oisn Kyne
Conor Kelleher
Oisn Kyne
Jack Beegan
Conor Kelleher
Jack Beegan
Various
Introduction
In this study we will be examining the differences between the Windows API for thread handling and
the Unix POSIX Threads. The body of the study is divided into three sections; one explaining the
history, use and implementation of threading systems in the Windows OS family, one looking into
the same areas in POSIX threads in a UNIX environment and, lastly, a section giving a side-by-side
comparison of the two. The ease of use for the developer and the subsequent popularity in modern
computing, the efficiency of the operations and the security involved (deadlock avoidance) are all
things that are going to be considered in this comparison. After the two thread APIs have been
subject to an in-depth analysis, we will conclude the study (touching on points brought up in the
comparison section) by giving a brief statement of our current view on the two and giving our
opinion as to which is the better implementation.
3|Page
Threads
The Microsoft Developer Network, the central hub for all documentation and resource material for
Windows developers, defines a thread as such:
A thread is the entity within a process that can be scheduled for execution. All threads of a process
share its virtual address space and system resources. Each process is started with a single thread, but
can create additional threads from any of its threads. (Multiple Threads, MSDN)
Windows threading systems are described as a high level way of operating with threads, they
simplify many of the processes which results in higher level code, which is generally easier to
interpret. The Intel Developer Zone has an article written by Clay Breshears (2006) which
complements the Windows Threads API due to its simplicity of use and elegance of design. This
simplicity is self-evident in the MSDN documentation on threads, the entire repository on thread
functions consists of 37 separate functions, many of which, stem from the same concepts. It is
absolutely undeniable that the thread API is as concise as possible.
The creation, interaction and destruction of threads are arguably some of the most important and
divergent aspects of thread APIs between different operating systems, in this section, we will look at
the implementation of these three tasks in the Windows operating systems, for further comparison
to be made later in this case study.
Thread Creation
Thread creation with the Windows API is a reasonably simple procedure; the API documentation
describes the action in C.
CreateThread(Security Attributes, Stack Size, Thread Function name, Arguments to be passed
to thread function, creation flags, &threadIdentifier);
4|Page
The security attributes declare whether or not a child process can inherit this thread, by default, this
is set to NULL and is not possible. The stack size is the size of the stack to be allocated to the thread
in bytes, (the system rounds this to the nearest page). The thread function name is interesting as you
pass a pointer to the address of the first line of a function to be executed in this thread; this is
followed by an array of arguments to be passed to said function. Any specific creation flags to be
used are passed then, such as creating an already suspended process. Finally, the address of a
variable to store the ID of the new thread is passed such that you can then access this thread with
that identifier, if this variable remains null after calling createthread, the creation failed and you
should react accordingly to this failure.
Thread Interaction
Windows provides many separate ways for threads to interact but the first and foremost thing to
keep in mind is that threads operate on shared memory in a single process, such that an API for
thread interaction isnt necessarily required. It is good practice to protect shared data with
semaphores or mutexes to prevent concurrent access and corruption of data due to competing
threads accessing the same data simultaneously.
Some of the available methods of multi thread management include:
I wont discuss the operation of these methods for interaction between threads in this case
study as the title is the similarities and differences between POSIX and WIN32 threads, whereas
these arent unique to one or the other, they merely have different implementations.
Thread Destruction
Thread destruction in a Windows environment is a reasonably simple process. The function to exit a
thread is ExitThread(status). This function is called when a thread that was created for a specific
function hits a return statement, or when it is called explicitly. ExitThread deallocates the threads
stack and any pending I/O is cancelled before the thread terminates. The status is the exit code for
the thread; by convention, a normal termination is a status code of 0. When a thread is terminated it
becomes signalled, indicating to any other threads waiting for its termination can now unblock.
If this thread is the last thread in a process, ExitProcess is also called and the process is ended too.
Interestingly, terminating a thread does not remove it from the system completely until all handles
to the thread are closed too.
5|Page
Threads
The POSIX Base Specification (IEEE Computer Society and The Open Group, 2013) provides formal
definitions of all components of the OS interface. Within this, threads are defined as:
A single flow of control within a process {consisting of} thread ID, scheduling priority and
policy, errno value, thread-specific key/value bindings, and the required system resources to
support a flow of control
By breaking a process into multiple flows of control, multiple tasks can be accomplished at the same
time, while also preventing the whole process stopping when part of a process is blocked. POSIX
threads, or Pthreads, also provide a much faster and lightweight solution to parallelism than process
forks, costing the programmer between a tenth and a hundredth of the execution time in
comparison, as per performance tests ran at research laboratories in California (Barney, Blaise Lawrence Livermore National Laboratory, 2014).
Thread Creation
Threads in POSIX are created using the pthread_create() function call. This function, defined within
the base specifications, is specifically designed to reflect the behavior of a process fork call, adapted
to accept arguments. (Tanenbaum & Herbert, 2014) It returns the thread identifier, TID, just as fork
would return the process identifier, PID. The format of this function call is:
pthread_create(tid,
attr,
start_fn,
arg);
(Lewis
&
Berg,
1995)
tid
This is a pointer to the address where the ID of the newly created thread will be stored. It is
of type pthread_t and must be declared within your program. (Butenhof, 1997)
attr
This is a pointer to the thread attribute, a variable of type pthread_attr_t. This contains the
details of the desired attributes of the thread. If set to null, the thread will be created with
6|Page
the default attributes which are process scope, nondetachable state, a default stack and
stack size, and a priority of zero. (Sun Microsystems, Inc., 2005)
The attributes that can be set within this variable are (Barney, Blaise - Lawrence Livermore
National Laboratory, 2014):
start_fn
This is the function that the thread will run. It must be of type void *, and take a single
argument, also of type void *.
arg
This is the argument of type void * which will be passed as a parameter to start_fn within
the execution of the thread.
The call returns immediately with the thread ID value and the calling thread continues executing its
instructions. The new thread is created in a ready state and, depending upon the scheduling
outlined in the thread attributes, it will begin running the function that was passed to it during its
creation independently from calling thread. (Butenhof, 1997)
Thread Interaction
To allow for synchronization of tasks across threads, pthreads implement three standard thread
synchronization variables; namely mutexes, semaphores, and condition variables. (Lewis & Berg,
1995)
These objects allow threads to share code, variables and resources while protecting them from
unintentionally altering program behavior due to concurrent attempts to access and alter data.
Mutex, semaphores and condition variables (also known as event semaphores) all have equivalents
in the Win32 threads library and do not differ significantly in behavior, making in-depth study here
redundant.
Thread Termination
Pthread termination occurs in four possible cases; termination of the parent process, cancellation by
another thread, an explicit exit call, or the return of a threads start functions.
If the initial thread of a program ( the thread running main() ) ends without waiting on its subthreads to finish, all sub-threads will disappear per the standard UNIX process behavior in what is
referred to as thread evaporation by David Butenhof. (Butenhof, 1997) This is preventable by
implementing a pthread_join() before the end of the main which requires the pthreads to run to
termination to complete.
Thread cancellation occurs when a thread tells another to exit by calling pthread_cancel() on the
identifier of the thread. This will immediately call pthread_exit() on the subject of the call, provided
7|Page
that its cancelability state is set to enabled, and its cancelability type is set as asynchronous (Lewis &
Berg, 1995). If the cancelability type is deferred, pthread_exit() will only be called when the thread
reaches one of the allowed cancellation points. Functions that constitute valid cancellation points
are listed in the POSIX API (IEEE Computer Society and The Open Group, 2013).
When pthread_exit() is executed, the thread enters a terminated state. In this state, it will continue
to hold most of the system and resources it used when being executed, including its stack, register
state and returned value of type void *. It will remain like this until it is either joined with another
thread, or is detached; only then are its resources recycled and its identifier freed. (Butenhof, 1997)
The return of a threads start function implicitly calls pthread_exit() which terminates the thread
much as a direct call would. The only distinction between the two is that the return type of the start
function can be extracted from any subsequent join or detach calls on the thread ID. (Mitchell, et al.,
2001)
8|Page
Thread Creation
POSIX and Windows Threads have a very similar way of creating threads. In fact, this is one of the
areas in which it seems the twos functionality can be directly mapped from one to the other. In the
Windows API, the user can call the CreateThread() function and, the POSIX equivalent of this is
Pthread_Create(). The only difference in the use of these two functions is the arguments that must
be passed to them. (CreateThread Function, MSDN), (pthread_create, QNX).
CreateThread()
lpThreadAttributes A pointer to a
SECURITY_ATTRIBUTES structure
dwStackSize The initial size of the stack
lpStartAddress A pointer to the function
to be executed by the thread
lpParameter A pointer to a variable to be
passed to the thread
dwCreationFlags A flag that controls the
creation of the thread
lpThreadId A pointer to a variable that
9 | Preceives
a g e the thread identifier.
Pthread_Create()
While the exact information being passed to the functions is different, both implementations
generate roughly the same result. In both cases, the functions are given as an argument a pointer to
the function that the thread will have to execute, information about how the thread should be able
to access memory, and a single argument that can be passed to the function.
Thread Interaction
As mentioned earlier in this case study, thread interaction is quite similar between Win32 and POSIX
threads (to the extent that their respective functions can almost be directly mapped from one to the
other) and, while the use of these functions for thread interaction are quite similar, the way they are
executed by the OS can result in some significant performance differences. One such example is in
the use of mutexes. As Larry Osterman explains in his article Why dont critical sections work cross
process? (2005), the windows implementation for mutexes requires the kernel to be accessed every
time you use it, which is not the case in the POSIX threads equivalent of mutexes unless there is
contention to be overcome via the kernel. For this reason, the Pthreads mutex is considered to be a
much more lightweight mutex. In Jeff Preshings article Always use a lightweight mutex (2011), he
compares the average time taken to use a mutex (looped 1,000,000 and divided to find average)
using both the Windows and the POSIX threads mutexes. Using the equivalent functions, he found
that the average time for locking and unlocking of the Windows mutex was 1.48s, whereas the
POISX mutex only took 92ns. This is clearly a much quicker implementation; however there are some
ways in which the use of Pthreads is made even quicker, for example, there is a condition to check
whether the thread creating the mutex is the only thread running, in which case, a mutex is
unnecessary and a trivial codepath is used, resulting in an average time of only 38ns on the same
system as before.
Thread Termination
Thread termination in Win32 and POSIX threads appear to be very similar, but do have some notable
differences. In the case of both, there are many ways for threads to exit. This can happen if the
starting routine for which the thread was created to execute returns normally after performing its
desired action, if the process that created the thread terminates before the thread terminates and,
(among others) if the respective thread-exit function is called on the thread. In Win32 threads, this
function is called ExitThread() and its POSIX counterpart is Pthread_exit(). Both functions are called
in the same way and each take an Exit_Code argument (usually 0). However, as mentioned earlier in
this case study, the ways in which these two are executed vary between the two Thread
implementations. Win32 threads are considered to be asynchronous in the way ExitThread() is
implemented as, here, if the thread is holding some resource or lock or has been allocated memory,
calling this function will not reallocate these resources, memory, etc. and so, deadlock can occur. In
POSIX threads, however, there is another condition in place to circumvent this issue. Here, threads
are assigned a state determining if cancellation should be enabled or disabled. In the case that it is
enabled, cancellation is asynchronous and functions just like Win32 threads, however if cancellation
is disabled, if the system reaches a Pthread_exit() call, it will use what is called deferred
cancellation, wherein the thread may run for an arbitrary time after cancellation , allowing critical
sections to be fully executed and resources to be released (Lewis & Berg, 1995).
10 | P a g e
Conclusions
Throughout our in-depth study of threads and the two most common types of them, we felt we
really developed a pretty thorough and comprehensive understanding of them as a concept, the
differences between the two most popular implementations of threads, and the benefits they
provide to the programmer and the end-user.
We focussed on the lifecycle of a thread as the crux of our comparisons, considering both POSIX and
Win32 threads as they proceeded from thread creation to thread termination, and the thread
interactions that occur in the times between.
In this manner, we were afforded a chance to see just how much they differed from one another, or
didnt differ as it so often proved to be, within each stage of their existence; whether it was the need
for different arguments during creation and the different default values used by each, or the
distinguishing speed increase pthreads provide during mutex-related actions, all the way to
distinctive deferred cancellation offered by POSIX threads when desired, making thread cancellation
less of a programming liability and much more usable.
These comparisons all led us to come to a single, shared consensus within the group regards threads
the flexibility to port across operating systems promised by POSIX threads is unrivalled in Win32
threads, making POSIX threads in UNIX and UNIX-like environments a much more desirable
implementation to work with given their programming elegance and overall ease of use.
11 | P a g e
References
Barney, Blaise - Lawrence Livermore National Laboratory, 2014. POSIX Threads Programming.
[Online]
Available at: https://computing.llnl.gov/tutorials/pthreads/
[Accessed 15 April 2015].
Butenhof, D. R., 1997. Programming with POSIX Threads. 1st ed. s.l.:Addison-Wesley.
IEEE Computer Society and The Open Group, 2013. Standard for Information Technology Portable
Operating System Interface (POSIX) Base Specifications, Issue 7, New York: IEEE Standards
Association.
Lewis, B. & Berg, D. J., 1995. PThreads Primer - A Guide to Multithreaded Programming, Mountain
View, California: SunSoft Press; Prentice Hall;.
Mitchell, M., Oldham, J. & Samuel, A., 2001. Advanced Linux Programming. 1st ed. Indianapolis,
Indiana: New Riders Publishing.
Silberschatz, A., Galvin, P. B. & Gagne, G., 2010. Operating System Concepts. 8th ed. s.l.:John Wiley &
Sons, Inc..
Sun Microsystems, Inc., 2005. Solaris Multithreaded Programming Guide, Santa Clara, CA: Sun
Microsystems, Inc..
Tanenbaum, A. S. & Herbert, B., 2014. Modern Operating Systems. 4th ed. Amsterdam: Prentice Hall.
API Index (Windows). 2015. API Index (Windows). [ONLINE] Available at:
https://msdn.microsoft.com/en-us/library/windows/desktop/hh920508(vs.85).aspx. [Accessed 04
April 2015].
Multiple Threads (Windows). 2015. Multiple Threads (Windows). [ONLINE] Available
at: https://msdn.microsoft.com/en-us/library/windows/desktop/ms684254(v=vs.85).aspx. [Accessed
08 April 2015].
Why Windows Threads Are Better Than POSIX Threads Clay Breshears (Intel) Oct. 19, 2006 | Intel
Developer Zone. 2015. [ONLINE] Available at: https://software.intel.com/enus/blogs/2006/10/19/why-windows-threads-are-better-than-posix-threads. [Accessed 08 April
2015].
Why Pthreads are better than Win32 threads. 2015. Why Pthreads are better than Win32 threads.
[ONLINE] Available at: https://software.intel.com/en-us/forums/topic/311081. [Accessed 19 April
2015].
CreateThread function (Windows). 2015. CreateThread function (Windows). [ONLINE] Available
at: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682453%28v=vs.85%29.aspx.
[Accessed 19 April 2015].
12 | P a g e
13 | P a g e