CISC2200 Threads
Spring 2015
Process
We learn the concept of process




A program in execution
A process owns some resources
A process executes a program => execution state, PC, …
We learn that bash creates processes to run user’s
command
We practice with process creation in assignment




2
Create a child process
Parent process
OS: Protection
Protection: mechanism for controlling access of
processes or users to resources (Files, memory
segment, CPU and other)
Systems generally first distinguish among users to
determine who can do what





3
User identities (user IDs): a unique name and number
User ID then associated with all files, processes of that user
to determine access control
Group identifier (group ID) allows set of users to be
defined, then also associated with each process, file
Hardware Support for protection
Dual-mode allows OS to protect itself and other system
components
A mode bit provided by processor hardware





Kernel mode for running kernel code
User mode for running user code
Privileged instructions only executable in kernel mode
System call: changes mode to kernel, return from call resets
it to user mode
“ps” command: reports user time, system time

4
Single-threaded Processes
5
Multithreading
Separate two
characteristics of process

Unit of dispatching =>
thread, lightweight process
 Unit of resource ownership
=> process, task
Multi-threading: ability of OS
to support multiple,
concurrent paths of execution
with a single process


6
Multithreading (cont’d)
Process: unit of resource
allocation/protection

An address space for its image

Protected access to resources

Inter-process communication
Thread:

A thread execution state

Saved context,

Execution stack

Access to memory/resource
of its process, shared with
other threads in the process


7
Why Multithreading ?
Many applications require a set of related units of
execution

Web Server example:




listening on port for client connection request
serving a client: read client request, serve the file
Can create multiple processes for them
Mainly performance consideration. Threads are




8
Faster to create a new thread, terminate a thread
Faster to switch between two threads within a process
More efficient communication between threads (without
invoking kernel)
Thread Usage (1)
Figure 2-7. A word processor with three threads.
Tanenbaum, Modern Operating Systems 3 e, (c) 2008 Prentice-Hall, Inc. All rights reserved. 0-13-6006639
Thread Usage (2)
Figure 2-8. A multithreaded Web server.
Tanenbaum, Modern Operating Systems 3 e, (c) 2008 Prentice-Hall, Inc. All rights reserved. 0-13-6006639
Thread Usage (3)
Figure 2-9. A rough outline of the code for Fig. 2-8. (a) Dispatcher
thread. (b) Worker thread.
Tanenbaum, Modern Operating Systems 3 e, (c) 2008 Prentice-Hall, Inc. All rights reserved. 0-13-6006639
Thread Usage (4)
Figure 2-10. Three ways to construct a server.
Tanenbaum, Modern Operating Systems 3 e, (c) 2008 Prentice-Hall, Inc. All rights reserved. 0-13-6006639
Benefits of Threads

Responsiveness

Resource Sharing

Economy

Scalability

10
Increase parallelism, allow application to take advantage of
multiprocessor architecture
Concurrent Execution
Parallel Execution (Multicore System)
11
POSIX Threads (1)
Figure 2-14. Some of the Pthreads function calls.
Tanenbaum, Modern Operating Systems 3 e, (c) 2008 Prentice-Hall, Inc. All rights reserved. 0-13-6006639
Blocking I/O vs non-blocking I/O
What we usually do to read/write from I/O is blocking I/O:
 read (src_fd, &buf, 1)
 cin >> op1 >> opcode >> op2;
 The calling process/thread blocks (enters into BLOCKED state)
until reading operation completes….
 Non-blocking I/O

int flags = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, flags | O_NONBLOCK);
read (fd, …) will return failure if there is nothing to read

Making blocking I/O after select, poll system call
 monitor multiple fds until one of them become ready —
commonly used in server programs
 call read() on file descriptor that is ready to read (i.e., it won’t
block the calling process)…
10
Blocking I/O
int main()
{
char buf[100];
int ret;
int count=0;
ret = read (0,buf,100);
if (ret>0){
write (1, "Read this:",9);
write (1, buf, ret);
} else
write (2, “failed in read.”,15);
}
17
0: file descriptor for standard input,
by default, it’s linked to keyboard
1: file descriptor for standard output,
by default, it’s linked to terminal
2: file descriptor for standard error,
by default, it’s linked to terminal
Same read(), write() system calls can be
used to read/write from I/O device, files,
sockets, …
We usually use higher-level library calls,
printf, scanf (in C), cin and cout (in C++)
Non-blocking I/O
int main()
{
char buf[100];
int ret;
int count=0;
get the current mode of file descriptor 0
(standard input), and set it to non-blocking
int flags = fcntl (0, F_GETFL,0);
fcntl (0, F_SETFL, flags | O_NONBLOCK);
do
{
ret = read (0,buf,100);
/* sleep (1); //put wait for 1 second before continue...
count++;
cout <<“Waited “ << count << “ seconds…\n”;
*/
} while (ret<=0);
buf[ret]='\0';
cout <<"Input"<<buf<<"End of INput”<<endl;
}
18
Solution: blocking I/O after select, poll
select, pselect,
synchronous I/O multiplexing
int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);
Timeout value
fd_set: a set of file descriptors
void FD_CLR(int fd, fd_set *set);
int FD_ISSET(int fd, fd_set *set);
void FD_SET(int fd, fd_set *set);
void FD_ZERO(fd_set *set);
 allows a program to monitor multiple file descriptors
 Calling process waits (is blocked) until
 one or more of the file descriptors become "ready" for some class of
I/O operation (e.g., input possible). A file descriptor is considered ready if it
is possible to perform corresponding I/O operation (e.g., read(2)) without blocking.
 Timer expires
 Ex: in connect-four game or other game program, implement a limited
time play (make a move within 10 seconds)…
19
User Threads vs Kernel Threads
Support for threads: provided at user level or kernel
level
User thread: Thread management done by user-level
threads library
Kernel thread: threads supported and managed by the
Kernel



12
Implementation of Threads: User-level





Implemented by a user-level
threads package
Kernel only knows about
processes
Thread library runtime system
schedule multiple threads within a
process
Pro: Lower overhead when
switching between threads (no
system call/trap involved)
Con: blocking I/O made by one
thread will block whole process
Tanenbaum, Modern Operating Systems 3 e, (c) 2008 Prentice-Hall, Inc. All rights reserved. 0-13-6006639
Many-to-One, User-level threads
Multiple user-level threads mapped to a single kernel
thread/process; user-level thread library implements all
threading functionalities
Advantage:





Thread switching requires no
kernel mode (save time)
Application specific scheduling
Run on any OS
Disadvantage:



One thread blocking blocks all
threads in process
A multithread app. cannot take
advantage of multiprocessor
Examples: Solaris Green Threads.

GNU Portable Threads
14
Thread
library
Implementation of Threads: Kernel


Implemented by a kernel
Kernel knows about threads,
schedule threads

Con: Overhead when switching
between threads (system call/trap
involved)

Pro: blocking I/O made by one
thread will NOT block whole
process

Question: Is Linux thread
implemented in OS kernel, or by
user-level threads
library? package
user-level
kernel threads package
Tanenbaum, Modern Operating Systems 3 e, (c) 2008 Prentice-Hall, Inc. All rights reserved. 0-13-6006639
One-to-One
Each user-level thread maps to kernel thread
Advantage? Disadvantage?
Examples




15
Windows NT/XP/2000, Linux, Solaris 9 and later
The Classical Thread Model (2)
Figure 2-12. The first column lists some items shared by all
threads in a process. The second one lists some items private
to each thread.
Tanenbaum, Modern Operating Systems 3 e, (c) 2008 Prentice-Hall, Inc. All rights reserved. 0-13-6006639
Hybrid Implementations
Figure 2-17. Multiplexing user-level threads
onto kernel-level threads.
Tanenbaum, Modern Operating Systems 3 e, (c) 2008 Prentice-Hall, Inc. All rights reserved. 0-13-6006639
Many-to-Many Model
User-level thread library:

thread creation, scheduling,
synchronization

Multiple user level threads mapped
to some (smaller of equal) number
of kernel threads

Programmer can adjust # of kernel
threads

Ex:


16
Solaris prior to version 9, Windows
NT/2000 with the ThreadFiber package
Thread
library
Thread Libraries
Thread library provides programmer with API for
creating and managing threads
Two primary ways of implementation




18
User-level library: library entirely in user space
Kernel-level library supported by the OS
Pthreads
A POSIX standard (IEEE 1003.1c) API for thread
creation and synchronization
API specifies behavior of the thread library,
implementation is up to developer of the library



May be provided either as user-level or kernel-level
Common in UNIX operating systems (Solaris, Linux,
Mac OS X)

19

#include <pthread.h>
#include <stdio.h>
int sum;
/* this data is shared by the thread(s) */
void *runner(void *param);
/* the thread */
int main(int argc, char *argv[])
{
pthread_t tid; /* the thread identifier */
pthread_attr_t attr; /* set of attributes for the thread */
if (argc != 2) {
fprintf(stderr,"usage: a.out <integer value>\n");
return -1;
}
if (atoi(argv[1]) < 0) {
fprintf(stderr,"Argument %d must be non-negative\n",atoi(argv[1]));
return -1;
}
pthread_attr_init(&attr);
/* get the default attributes */

/* create the thread */
pthread_create(&tid,&attr,runner,argv[1]);
pthread_join(tid,NULL); /* now wait for the thread to exit */
printf("sum = %d\n",sum);
}
/** * The thread will begin control in this function */
void *runner(void *param)
{
int i, upper = atoi(param);
sum = 0;
if (upper > 0) {
for (i = 1; i <= upper; i++)
sum += i;
}
pthread_exit(0);
}

21
To compile:
gcc –pthread main.c
Java Threads

Java threads are managed by the JVM

Typically implemented using the threads
model provided by underlying OS

Java threads may be created by:


22
Extending Thread class
Implementing the Runnable interface
Threading Issues
Complication due to shared resources: e.g., global variables,
system info for the process …

Semantics of fork() and exec() system calls
Thread cancellation of target thread



Asynchronous or deferred
Signal handling
Thread pools


23
Is swap thread-safe?
int t;
void swap(int *x, int *y)
{
t = *x;
*x = *y;
// hardware interrupt might invoke isr() here!
*y = t;
}
Can swap function be called by multiple threads within a
program?
34
Making Single-Threaded Code
Multithreaded
Figure 2-19. Conflicts between threads
over the use of a global variable.
Tanenbaum, Modern Operating Systems 3 e, (c) 2008 Prentice-Hall, Inc. All rights reserved. 0-13-6006639
Semantics of fork() and exec()
Does fork() duplicate only the calling thread or all
threads?


Some Unix provides two version of fork(), one duplicate all
threads and another duplicates only the thread making fork()
calls
exec() replace the entire process with the new program,
including all threads

24
Thread Cancellation
Terminating a thread (referred to as target thread)
before it finishes
Two general approaches:


Asynchronous cancellation terminates target thread
immediately


Problematic if target thread is updating shared data, or has
allocated some resource
Deferred cancellation allows target thread to periodically
check (at cancellation points) if it should be cancelled

25
Signal Handling
Signals are used in UNIX systems to notify a
process that a particular event has occurred
•
1.
2.
3.
Signal is generated by particular event: segmentation fault,
division by error, ctrl-c, kill ….
Signal is delivered to a process
Signal is handled by the process
A signal handler is used to process signals
•
•
26
Default signal handler, user-defined signal handler
Signal Handling & multi-threading
Deliver signal to all threads within the process, or just one
particular thread ?
Options:
•
•
–
–
–
–
27
Deliver signal to the thread to which the signal applies
Deliver the signal to every thread in the process
Deliver the signal to certain threads in the process
Assign a specific thread to receive all signals for the process
and process the signals
Thread Pools
Create a number of threads in a pool where they
await work
Advantages:




28
Usually slightly faster to service a request with an existing
thread than create a new thread
Allows the number of threads in the application(s) to be bound
to the size of the pool
Windows XP Threads
Implements the one-to-one mapping, kernel-level
Each thread contains






A thread id
Register set
Separate user and kernel stacks
Private data storage area
The register set, stacks, and private storage area are
known as the context of the threads
The primary data structures of a thread include:





29
ETHREAD (executive thread block)
KTHREAD (kernel thread block)
TEB (thread environment block)
Linux Threads
Linux does not distinguish between processes and threads
Linux refers to them as tasks rather than threads


A flow of control within a program

System call clone(): create a new task, with flags specify the
level of sharing between parent and child task

CLONE_FS: file system info is shared
CLONE_VM: memory space is shared
CLOSE_SIGHAND: signal handlers are shared
CLONE_FILES: the set of open files is shared






How to create a task with similar sharing of threads as described in
this class ?
How to create a task with similar sharing as process ?
30