GoConqr has a new look! Let us know what you think.

Notes

OS Chapter 4: THREADS N CONCURRENCY

Ivan Blaskic Computer Science English 47 pages

Content of the notes (47)

Page 1

Objectives

basic components of threads versus processes

benefits and challenges of multithreaded process design

implicit threading: thread pools, fork-join, Grand Central Dispatch

Windows and Linux representing threads

multithreaded app desing using Pthreads, Java and Windows API's for MT

Page 2

Overview

basic unit of "CPU utilization"

thread ID, PC, register set, stack - one thread

other threads belonging to the same process - code, data + other OS resources

single-threaded vs multi-threaded process

Motivation

app creating thumbnails from many pictures

word processor - displaying graphics, responding to keystrokes, spell-check

design for leveraging capabilities on multicore systems - CPU intensive tasks

web server example - request 1) resume listening to clients 2) service request

kernel multithreaded - boot time example

Page 3

Benefits

responsiveness - part blocked still running or performing lengthy operation, UI

resource sharing - having multiple threads/activities sharing same address space

economy - more economical creation and context-swithing threads - time and memory save

scalability - threads running in parallel on different processing cores

Page 4

Multicore Programming

more computing cores on single processin chip (CPU)

using these multiple computing cores

concurrent vs parallel execution / single-core vs multicore system

concurrency possible even without parallelism - before multipocesors n MC

Programming Challenges

Identifiying tasks - areas that can be divided in seperate independent tasks

Balance - ensuring each task performs equal work of equal value

Data splitting - dividing data accessed and manipulated to run on separate Cs

Data dependency - examine data for dependecies between 2+ tasks - sync

Testing and debugging - more difficult

Page 5

Amdahl's Law

formula for performance gains from adding additional computing cores to app

app has both serial and parallel components

speedup <= (1) / [S+((1-S)/N)] --> serial percentage of the core (S), # of cores (N)

Types of Parallelism

data and task parallelism

data - distributing subsets of the same data across computing cores

task - distributing tasks across computing cores - unique tasks - data whatever

application might be hybrid between these two

Page 6

Multithreading Models

threads support at user level or by the kernel - user vs kernel threads

kernel threads - managed and supported by OS directly

virtually all OSs support kernel threads

many-to-many, one-to-one and many-to-one model

Many-to-One

maps many user-level threads to one kernel thread

thread management is done by thread library in user space - efficient

one block syscall blocks the entire process

one thread has access to the kernel at a time - unables multitple threads running in parallel on multicore systems

Green Threads - thread library available for Solaris systems - in early Java

Page 7

One-to-one Model

each user thread mapped to kernel thread

more concurrency provided - another thread can run when blocking reached

allows multiple threads running in parallel on multiprocessors

user thread requiring a kernel thread creation - downfall

large number of kernel thread - "Boooo"

implemented by Windows and Linux + OSs

Many-to-many Model

mapping many user-level threads to smaller or equal number of kernel threads

specific to app or machine

when one thread performs blocking syscall - kernel can schedule another thread

Page 8

Models Compared

many-to-one --> no parallelism - kernel can schedule only one kernel thread at a time

one-to-one --> cannot create too many threads within an application (most popular)

many-to-many --> as many user threads ap, corresponding kernel threads run in parallel on MP

Two-level model

many-to-many that allows a user-level thread to be bound to a kernel thread

Page 9

Thread Libraries

providing API for creating and managing threads to programmers

entirely in user mode w/o kernel support (no syscalls) & kernel-level library OS supported

main libraries: POSIX Pthreads, Windows and Java

Page 10

Pthreads - POSIX standard extension - either a user-level or a kernel-level library

Windows thread library - kernel-level library

Java thread API allows threads to be created and managed directly in Java program

since JVM running on top of host OS, Java thread API generally implemented using thread library of the host system

Java Threads on Windows - implemented using Windows API;

Java Threads on UNIX, Linux and macOS - implemented using Pthreads

Posix and Windows threading

any data globally declared outside of any function are shared among all threads belonging to the same process

Java has no equivalent notion of global data so access to shared data must be explicitly arranged between threads

Page 11

Example:

Summation of a Non-negative Integer, n using a multithreaded program in a separate thread

asynchronous threading

once parent creates a child thread it resumes its execution so they execute concurrently, independent of one another

little data sharing btw independent threads

commonly used for multithreaded server or designing responsive UI

synchronous threading

parent thread creates one or more children - waits for them to terminate

child threads can execute concurrently

involves significant data sharing among threads

i.e. parent thread may combine the results calculated by its children

Page 12

Pthreads - POSIX standard (IEEE 1003.1C)

API for thread creation and synchronization

specification for thread behavior not implementation!

many systems implement Pthreads specification - most UNIX-type systems

such as Linux and macOS

Page 13

Page 14

Pthreads API - constructing multithreaded C program calculating summation using it

in Pthreads program - separate threads begin execution in a specified function

runner() function is that function in example

single thread of control begins in main() - parent process

second thread created - pthread_create(%tid, &attr, runner, argv[1]);

both threads sharing global data sum

c program : #include

pthread_t tid declaring identifier

pthread_attr_t attr representing the attributes - stack size, scheduling...

pthread_attr_init initialization of these

child process - runner() function

pthread_join (tid, NULL); pthread_exit();

create/join strategy used so parent waits for child's termination

Page 15

Pthreads API - joining on ten threads by using pthread_join() function

#define NUM THREADS 10

pthread_t workers [NUM_THREADS]

for (int i=0; i < NUM_THREADS; i++)

pthread_join(workers[], NULL);

Page 16

Windows Threads

#include

DWORD WINAPI Summation (LPVOID Param) //LPVOID - pointer to void

DWORD Upper = *(DWORD*) Param;

for (DWORD i = 1; i <= Upper; i++)

DWORD ThreadId; //unsigned 32-bit integer

HANDLE ThreadHandle

ThreadHandle = CreateThread (NULL, 0, Summation, &Param, 0, &ThreadId);

security info, stack size, flag for start or suspended state

WaitForSignleObject (ThreadHandle,INFINITE); or WaitForMultipleObjects();

# of objects to wait, pointer to array of them, all objects signaled? flag, timeout duration

CloseHandle (ThreadHandle);

Page 17

Java Threads

rich set of features for the creation and management of threads

all programs at least a single thread of control (main())

2 techniques for explicitly creating threads

creating new thread derived from the Thread class

defining a class that implements Runnable interface

pulic void run() - called when we call the start() method

the code in the run() method of a class that implements Runnable is what executes in a seperate thread

class Task implements Runnable { public void run() { System.out.println ("I am a thread."); } }

creating a Thread object and passing it an instance of a class that implements Runnable followed by invoking the start() method on Thread object

Thread worker = new Thread (new Task());

worker.start(); //allocating mem, initializing new thread in JVM, call of run()

Page 18

Java Threads

waiting for summation threads to finish - join() method

try {

worker.join();

}

catch (InterruptedException ie) { }

java.util.concurrent package - thread creation organized around Executor interface:

public interface Executor {

void execute ( Runnable command);

}

Executor service = new Executor;

service.execute(new Task());

Callable interface similar to Runnable - returns a result - Future objects

Page 19

Java Threads

thread creation in Java inolves

creating a Thread object

passing it an instance of a class that implements Runnable interface

followed by invoking start() method on Thread object

Thread worker = new Thread (new Task());

worker.start();

allocating memory and initializating new thread in JVM

call of run() method - Thread eligible to be run by JVM

Page 20

Java Executor Framework

new concurrency features - java.util.concurrent package

thread creation organized around Executor interface

public interface Executor {

void execute (Runnable command);

}

Executor service = new Executor;

service.execute (new Task());

producer - consumer model

tasks implementing the Runnable interface produced by user

threads executing these tasks consume them

provides mechanism for communication between concurrent tasks

Callable interface rather than Runnable interface for return result

Return result is Fututre object --> get() method from Future interface

submit() method - as execute() method, but returns result

Page 21

Implicit Threading

JVM typically implemented on top of a host OS

specification for JVM not indicating how Java threads are mapped to OS

leaving that decision to implementation of JVM

Windows OS one-to-one model - Java thread (JVM) = kernel thread

additionally - relationship btw Java thread library and HOS thread library

JVM for Windows OS - Windows API; Unix fam OS - Pthreads API

Page 22

Implicit Threading (benefit for developers; challenge for machines)

difficulty: growth of multicore processing - apps contain 100s threads

way to address these, and support design of concurrent and parallel apps

transfering creation and management of threading from app developers to compilers and run-time libraries

4 alternative approaches to designing applications that take advantage of multicore processors through implicit threading

developers identify tasks not threads that can run in parallel

function that run-time library maps to separate thread

using many-to-many model

libraries take care of specific details you identify parallel tasks

Page 23

Thread Pools (TP) Why

issues when server creates new thread

amount of time required to create the thread

thread will be discarded once it has completed its work

no bound on the number of threads concurrently active in system

possibly exhausting system resources - CPU time or memory

solution - thread pool

Android - remote service using thread pool handles multiple concurrent requests

Page 24

Thread Pools (TP) Concept

creating number of threads at start-up and placing them into a pool

threads sit and wait for work

server receives request - submits it to the TP and waits for new request

if there is available thread in pool - it's awakened - request service imm

if no available thread - task is queued until one becomes free

completed service followed by return to pool and wait for more work

work better when tasks submitted can be executed asynchronously

Page 25

Thread Pools (TP) Benefits

faster than creating new thread

limited number of threads existing at one point

separation btw task to be performed and mehanics of creating it

different strategies could be used for running it

# of threads in TP based on # of CPUs in system, amount of physical memory, expected number of concurrent client requests...

dynamically adjusting according to usage patterns

Apple's Grand Central Dispatch

Page 26

Thread Pools

Windows API provides several functions

DWORD WINAPI PoolFunction (PVOID Param) {

/* this function runs as a separate thread. */

}

pointer to this function is passed to TP API

one thread from pool executes this function

i.e. QueueUserWorkItem(&PoolFunction, NULL-parameters, 0)

Page 27

Java Thread Pools - java.util.concurrent including API for several TP architectures

Single thread executor - newSingleThreadExecutor() - pool of size 1

Fixed thread executor - newFixedThreadPool(int n) - specified # of threads

Cached thread executor - new CachedThreadPool() - unbounded TP

Executor class methods for TP creation - static ExecutorService 1, 2 or 3

each creates and returns an object instance that implements ExecutorService interface extending Executor interface so we can invoke the execute() method on this object

shutdown() method invoked results in rejection of additional tasks from TP and shuts down once all existing tasks have completed

Page 28

Fork Join - synchronous model - explicit thread creation

main parent thread creates (forks) one or more child threads

main thread waits for childrend to terminate and join with it retrieving and combining their results

fork-join parallelism - threads not constructed during fork stage but rather parallel tasks are designated --> libraries responsibility is to have threads created and assign tasks to threads

synchronous version of TP where library determines number of threads tbc

main --> fork --> task --> join --> main

--> fork --> task --> join -->

Page 29

Fork Join in Java

introduced in API designed to be used with recursive divide-and-conquer algorthms as Quicksort and Mergesort

separate tasks are forkd during divide step & assigned smaller subsets

model: if problem small enough solve it directly; if not, fork on 2 subsets

after forks - join subtask 1, join subtask 2 and return combined results

new thrad pool - ForkJoinPool - can be assigned tasks inheriting the abstract base class ForkJoinTask - for now - SumTask class

ForkJoinPool pool = new ForkJoinPool();

SumTask task = new SumTask (0, SIZE-1, array);

int sum = pool.invok(task); --> submition of initial task to the TP

Page 30

Fork Join in Java

SumTask is class implementing D&C algorithm for sum of the array using FJ

fork() until able to compute() on subset, join() block until task completes and returns the result from compute()

SumTask extends RecursiveTask<Integer> which is derived from ForkJoinTask<V>

work stealing algorithm when thread's queue is empty

Page 31

OpenMP

set of compiler directives and API for programs written in C, C++ or FORTRAN

provides support for parallel programming in SM environments

identifies parallel regions as block of code that may run in parallel

developers insert compiler directives into their code at parallel regions so OpenMP run-time library executes the region in parallel

#pragma omp parallel - directive that creates as many threads as there are processing cores in system

#pragma omp parallel for - OpenMP divides the work contained in the for loop among the threads that it has created in response to compiler directive

# of threads can also be set manually

data private to thread or shared

Page 32

Grand Central Dispatch (GCD)

combination of run-time library, an API, and language extensions allowing developers to identify sections of code (tasks) to run in parallel

it manages most of the details of threading - as OpenMP

scheduling for run-time execution - placing tasks on dispatch queue

removing task from queue follows assigning it to available thread from TP that GCD manages

2 types of dispatch queues: serial & concurrent

serial DQ or private DQ: tasks removed in FIFO order - once removed it must complete before other's execution

main queue - each process has its own serial DQ and developers can create additional local serial queues for that process

concurrent DQ or global DQ: tasks placed on concurrent queue are removed in FIFO order, but several can be removed at a time

Page 33

GCD

4 primary quality-of-service classes of system-wide concurrent queues

user-interactive class: tasks interacting with user

user-initiated class: same as user-interactive but longer processing times

utility: tasks requiring longer time to complete

background: not visible to the user and not time sensitive

2 ways of expressing tasks submitted to DQ

​​​​​​​for C, C++ and objective-C languages, GCD identifies a language extension - block - self contained unit of work; ^{}

for Swift programming language, GCD identifies task using a closure - similar to block - expresses a self-contained unit of functionality minus the leading caret ˇ --> dispatch_async (queue, {})

GCD TP composed of POSIC threads internally

releaed by Apple, ported to the FreeBSD OS

Page 34

Intel Thread Building Blocks (TBB)

template library that supports designing parallel applications in C++

no special compiler or language support needed

developers specify tasks that can run in parallel

TBB task scheduler maps these tasks onto underlying threads

provides load balancing - is cache aware - quicker execution

rich set of features provided by TBB

templates for parallel loop structures, hash map, queue, vector

concurrent data structures provided

thread-safe versions of the C++ std template library data structures

Page 35

TBB

parallel_for template provided by TBB

parallel_for (range body)

iteration space - size_t(0), n

an operation to be performed - [=] (size_t i) {apply(v[i]);}

creation of number of tasks that operate on chunks made by dividing the loop iterations

creation of number of threads and assigning tasks to available threads

developer can manually specify the size of the chunks too

Page 36

The fork() and exec() System Calls

some versions of UNIX - fork() duplicate all threads -- some - duplicate this

if thread invokes exec() system call - program specified in the parameter to exec() will replace the entire process - including all threads

which version of fork() to use depends on application

if exec() after forking then duplicating all is unnecessary - only calling t.

o.w. separate process should duplicate all threads

Page 37

Signal Handling

signal use in UNIX - notifying process that a particular event has occurred

signal pattern

signal generated by the occurrence of a particular event

sinal delivered to a process

signal handled by process

synchronous signals - sent to this process

illegal memory access or division by 0

signal delivered to the same process performing the operation

asynchronous signals - sent to another process

signal is generated by an event external to a running process so process receives it asynchronously

process termination with specific keystrokes (<control><C>) or timer

Page 38

Signal Handling

2 possible handlers

default signal handler (DSH)

user-defined signal handler (UDSH)

every signal has DSH that kernel runs when handling that signal

could be overriden by UDSH

signal delivering options

deliver signal to the thread to which it applies

deliver signal to every thread in process

deliver signal to certain thread in process

assign a specific thread to receive all signals for the process

standard UNIX method for delivering a signal: kill (pid_t pid, int signal)

specifies to which process (pid) to deliver a signal - first non-blocking?

Windows allows to emulate signals: asynchronous procedure calls (APC)

delivered to a particular thread rather than process - straight-forward

Page 39

Thread Cancellation

termination of thread before its completion

one finds result - all have to be canceled

target thread - has to be canceled

asynchronous cancellation - one thread imm terminates target thread

deffered cancellation - target thread periodically checks whether to terminate

deffered safer option since it has a flag giving info if thread is ready for cancellation

Pthreads - pthread_cancel(tid) function --> only a request to cancel

create, cancel, join - types of cancellation: ASYNC, DEFERRED, OFF

takes place only when thread reaches cancellation point

pthread_testcancel() function + cleanup handler

Java thread cancellation - Thread worker; worker.interrupt(); isInterrupted() ?

Page 40

Thread-Local Storage (TLS)

often in multithreaded programming threads belonging to process share data

TLS is data needed in situation where each thread needs its own copy of data

transaction-processing example - each transaction has unique identifier

TLS vs local vars - TLS are rather visible not only during function invocationbut rather across them all

similar to static data - difference being - TLS data is unique to each thread

Java providing: ThreadLocal class w set() and get() methods

Pthreads providing: pthread_key_t - key specific to each thread used for TLS

C# language: only [ThreadStatic] storage attribute is needed to declare TLS

gcc: _thread keyword for declaring TLS: static _thread int threadID;

Page 41

Scheduler Activations

communication between the kernel and thread library required by

many-to-many and two-level models

allowing number of kernel threads to be dynamically adjusted to help ensure the best performance

many systems placing intermediate data structure between user and kernel threads - lightweight process (LWP)

for user-thread library - appears to be a virtual processor on which app can schedule user thread to run

attached to Kernel thread which OS schedules to run on physical processor

kernel thread blocks - LWP blocks - user-level thread blocks

LWP is required for each concurrent blocking system call

Page 42

Scheduler Activation

scheme for communication btw user-thread library and kernel

kernel provides an app w set of virtual processors (LWPs)

app can schedule user threads on available virtual processor

kernel must inform app about certain events - upcall procedure

handled by thread library with upcall handler that must run on a virtual processor

example - app thread is about to block - allocaing new virtual processor for app running upcall handler - blocking/unblocking thread

Page 43

Windows Threads

app running as a separate process

each process may contain one or more threads

Windows API and one-to-one mapping is described earlier

general components of a thread include

thread ID uniquely identifying thread

register set representing the status of the processor

PC

user stack, when thread running in user mode; o.w. kernel stack

private storage area used by run-time libraries and DLLs (dynamic link)

context of the thread - stacks, register set and private storage area

primary data structures of thread include

ETHREAD - executive thread block

KTHREAD - kernel thread block

TEB - thread environment block

Page 44

Windows Threads

ETHREAD key components:

pointer to the process to which thread belongs

address of the routine in which the thread starts control

pointer to corresponding KTHREAD

...

KTHREAD includes:

scheduling and synchronization information for thread

kernel stack

pointer to corresponding TEB

...

TEB - only one user-space DS; accessed when thread is running in user mode

thread identifier

user-mode stack

array for thread-local storage (TLS)

...

Page 45

Linux Threads

fork() and clone() system calls

not distinguishing between processes and threads

Linux . uses term task - rather than process or thread - when reffering to a flow of control within a program

inoking clone() with a set of flags determining how much sharing takes place btw parent and child task

CLONE_FS, file system info shared

CLONE_VM, same memory space shared

CLONE_FILES, open files shared

using clone() equivalent to creating a thread since parent task shares most of its resources with its child task

no flags in clone() - no sharing - similar to fork() system calls

Page 46

Linux Threads

unique kernel data structure - struct task_struct - exists for each task in system

contains pointers to other data structures where data for the task are stored

i.e. data structure representing the list of open files, signal-handling info and virtual memory

fork() invoked - new task created - new copy of all associated data structures of parent process

clone() invoked - new task is created - pointing to the data structure of the parent task depending on the set of flags passed to clone()

+ flags in clone() allows it not only to create a task that behaves as a process or thread but also as a container allowing creating multiple Linux systems under a single Linux kernel run. in isolation to one another - virtualization

Page 47

Information

Description
Computer Science Note on OS Chapter 4: THREADS N CONCURRENCY, created by Ivan Blaskic on 20/10/2018.
Created by
Ivan Blaskic
Views
0
Rating

Feedback

What is it about?

What do you think of the new look?

How do you like it?