#include#include #define NUM_THREADS 4 void *threadFunc (void *arg){ int *p = (int*)pArg; int myNum = *p; printf("Thread number %d\n", myNum); return 0; } int main(void){ int i; pthread_t tid[NUM_THREADS]; for (i=0; i < NUM_THREADS; i++){ /* create/fork threads */ pthread_create(&tid[i], NULL, threadFunc, &i); } for (i=0; i < NUM_THREADS; i++){ pthread_join(tid[i], NULL); } return 0; }
PThread Creation
#include <stdio.h> #include <pthread.h> void *foo (void *arg){ printf("Foobar!\n"); pthread_exit(NULL); } int main(void){ int i; pthread_t tid; pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSYEM); pthread_create(NULL, &attr, foo, NULL); return 0; }
Compiling PThreads
1. #include
2. compile source with -lpthread or -pthread
Intro to OS ~ ==> gcc -o main main.c -lpthread
3. check return values of common functions
#include#include #define NUM_THREADS 4 void *hello (void *arg){ printf("Hello Thread\n"); return 0; } int main(void){ int i; pthread_t tid[NUM_THREADS]; for (i=0; i < NUM_THREADS; i++){ /* create/fork threads */ pthread_create(&tid[i], NULL, hello, NULL); } for (i=0; i < NUM_THREADS; i++){ pthread_join(tid[i], NULL); } return 0; }
PThreads
PThread == POSIX Threads
POSIX == Portable Operating System Interface
POSIX Thread
– POSIX versions of Birrell’s API
– specifies syntax and semantics of the operations
Thread, Fork(proc, args), Join(thread)
pthread_t aThread; int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void * (*start_routine)(void *) void *arg); int pthread_join(pthread_t thread, void **status);
stack size, inheritance, joinable, scheduling policy, priority, system/process scope
Condition Variable API
Condition type
Wait(mutex, cond)
– mutex is automatically released z re-acquired on wait
Signal(cond)
– notify only one thread waiting on condition
Broadcast(cond)
– notify all waiting threads
Mutexes
Can be accessed by reading shared variable
create new list element element set e.value = X read list and list.p_next set e.pointer = list.p_next set list.p_next = e
Mutex, Lock(mutex), blocked_threads
List<int> my_list; Mutex m; void safe_insert(int i){ Lock(m){ my_list.insert(i); } }
for i=0..10 producers[i] = fork(safe_insert, NULL) consumer = fork(print_and_clear, my_list) Lock(m){ list->insert(my_thread_id) } // unlock Lock(m){ if my_list.full -> print; clear up to limit of elements of list else -> release lock and try again (later) }
Condition Variable
Lock(m){ while (my_list.not_full()) Wait(m. list_full); m_list.print_and_remove_all(); } Lock(m){ my_list.insert(my_thread_id); if my_list.full() Signal(list_full); }
Basic Thread Mechanisms
Thread data structure
– identify threads, keep track of resource usage…
mechanisms to create and manage threads
mechanisms to safely coordinate among threads
running concurrently in the same address space
Processes, Threads
VA_p1, VA_p2
Concurrency Control & Coordination
-Mutual Exclusion
exclusive access to only one thread at a time
-Mutex
waiting on other threads
– specific condition before proceeding
Threads and Thread creation
Thread type
– thread data structure
Fork(proc, args)
– create a thread
– not unix fork
Join(thread)
^ terminate a thread
Thread thread1; Shared_list list; thread1 = fork(safe_insert, 4); safe_insert(6); join(thread1); // Optional
What about I/O?
ready queue -> cpu
I/O <- I/O queue <- I/O request
time slice expired, fork a child, wait for an interrupt
Scheduler Responsibility
- maintaining the ready queue
- decision on when to context switch
P1(web server) P2(Database)
mm, cpu
Inter Process communication
IPC mechanisms
-transfer data/info between address spaces
-maintain protection and isolation
Threads to the rescue!
threads -> multithreaded process -> core1, core2, core3 …
parallelization => speed up
specialization => hot cache!
efficiency => lower mm requirement & cheaper IPC
Are threads useful on a signle CPU?
or when (#of Threads) > (# of CPUs)?
t_ctx_switch -> t_idle -> t_ctx_switch
A process
State of execution
-program counter, stack
Parts & temporary holding area
May require special hardware
-I/O devices
What is a process?
OS manages hardware on behalf of applications
application == program of disk, flash memory(static entity)
process == state of a program when executing loaded in memory(active entity)
What does a process look like?
stack, heap, data, text
address space == “in memory”
representation of a process
physical addresses: locations in physical memory
How does the OS know what a process is doing?
-program counter
-cpu registers
-stack pointer
Process Control Block(PCB)
registers
memory limits
list of open files
priority
signal mask
CPU scheduling info
-PCB created when process is created
-Certain fields are updated when process state changes
-Other fields change too frequently
CPU process
running, ready state
mechanisms for process creation
-fork == copies the parent PCB into new child PCB
child continues execution at instruction after fork
-exec == replace child image, load new program and start from first instr.
unix-based os, the parent of all process: init
the parent of all app processes: zygote
OS must
-preempt
-schedule
-dispatch
System call
User process, kernel
to make a system call an application must
– write argoments
– save relevant data at well-defined location
– make system call
User/Kernel Transitions
・hardware supported
e.g. traps on illegal instructions or memory accesses requiring special privilege
・involves a number of insturctions
e.g. -50-100ns on a 2GHz machine running Linux
・switches locality
-> affects hardware cache
・process management
・file management
・device management
kill
setgid
mount
sysctl
monolithic OS
+everthing included, inlining, compile time optimizations
-customization, portability, manageability, momory footprint, performance
module OS
-operating system, module(Interface)
Microkernel
operating system, address space, threads
Linux architecture
Hardware(cpu, memory, disks, terminal), Linux operating system(process management, memory management, the file system;I/O, etc), standard library(open, close, read, write, fork, etc), standards utility programs(shell, editor, compilers, etc), users
Abstraction or Arbitration
arbitration(R): distributing memory between multiple processes
abstruction(B): supporting different types of supeakers, interchangeable access of hard disk or SSD
Desktop, Embedded
microsoft windows, unix-based(mac os x(BSD), linux)
android, ios, Symbian
Abstractions
-process, thread, file, socket, memory page
Mechanism
-create, schedule
OS Element: memory management example
Abstractions: memory page
mechanism: allocate, map to a process
Policies: least recently used -LRU
Design princples
separation of mechanism 2 policy
-implement flexible mechanisms to support many polices
-e.g, LRU, LFU, random
Optimize for common case
– where will the os be used?
– what will the user want to execute on that machine?
– what are the workload requirements?
OS Protection Boundary
user/kernel protection boundary
privileged mode, kernel-level
user-kernel switch is supported by hardware
-trap instructions
-system call
open(file), send(socket), malloc(memory)
-signals