Title: Linux Programming Process
1Linux Programming Process Threads
2Process Overview
- viewing process id
- printf (The process ID is d\n, (int) getpid
()) - printf (The parent process ID is d\n, (int)
getppid ()) - viewing active processes
- system call
- return_value system (ls -l /)
3Process Management
- process creation fork() and exec()
- exec family naming
- p means it searches the path for the given
program name - v means it accepts arg list as a null terminated
array of pointers to strings (execv, execvp,
execve) - e means it accepts an array of environ var as an
argument - exec never returns unless an error occurs
- process termination
- kill 9 pid OR kill KILL pid
- priority adjustment
- nice n 10 sort phone.txt gt output.txt
- decreases the priority 10 levels
4Signal
- A notification of an event to a running process
- On receiving a signal, a process
- performs user defined action if defined
- performs default action otherwise
- the action on a signal
- shouldnt call syscall, lib function, IO
operations, .. - should be minimal
- another signal arrives while a signal is being
processed - race condition for a global variable
- the global variable to write should be defined as
- sig_atomic_t
5Signal Handler
sig_atomic_t sigusr1_count 0 void handler
(int signal_number) sigusr1_count int
main () struct sigaction sa memset (sa,
0, sizeof (sa)) sa.sa_handler handler
sigaction (SIGUSR1, sa, NULL) / Do some
lengthy stuff here. / / ... / printf
(SIGUSR1 was raised d times\n,
sigusr1_count) return 0
6Clean Up Child processes
- wait() syscall
- waits till child process exits or returns error
- what happens if there is no wait()
- the child process remains as a zombie process
- otherwise, the exit information is lost
- init process cleans up zombies
- you can clean up zombies
- use non-blocking wait3() or wait4() periodically
- or catch SIGCHLD signal sent from Linux
7Clean Up Zombies
sig_atomic_t child_exit_status void
clean_up_child_process (int signal_number)
/ Clean up the child process. / int status
wait (status) / Store its exit status
in a global variable. / child_exit_status
status int main () / Handle SIGCHLD by
calling clean_up_child_process. / struct
sigaction sigchld_action memset
(sigchld_action, 0, sizeof (sigchld_action))
sigchld_action.sa_handler clean_up_child_proces
s sigaction (SIGCHLD, sigchld_action,
NULL) / Now do things, including forking a
child process. / / ... / return 0
8Threads Review
- Threads in the same address space
- share everything in the address space
- lighter than process
- no protection between threads
- Why is it lighter than process?
- no overhead for address space management
- no page table(no TLB misses)
- cache misses
- Two kinds of threads
- kernel threads (Pthreads, Solaris Threads, )
- user level threads
9Address Space with Threads
thread
thread
thread
files
registers
registers
registers
stack
stack
stack
10Introduction to Pthreads
- POSIX
- IEEE API standard for Unix family OSes
- includes threads standard pthreads
- tutorials
- http//www.mit.edu8001/people/proven/pthreads.htm
l - http//dis.cs.umass.edu/wagner/threads_html/
- compile
- gcc -flags source_file.c -lpthread (-lposix4)
11Thread Creation
pthread_t a_thread pthread_attr_t
a_thread_attribute void
thread_function(void argument) char
some_argument pthread_create(
a_thread, a_thread_attribute, (void
)thread_function, (void )
some_argument)
- a_thread thread handle
- a_thread_attribute
- only stack size can be specified with the current
version - use NULL to accept the default values
- thread_function code to execute
- some_argument arguments to that code
12pthread_create() Example
void print_message_function( void ptr )
char message message (char ) ptr
printf("s ", message) main()
pthread_t thread1, thread2 char message1
"Hello" char message2 "World"
pthread_create( thread1, pthread_attr_default,
(void)print_message_functio
n, (void) message1) pthread_create(thread2
, pthread_attr_default,
(void)print_message_function, (void)
message2) / two threads are racing /
exit(0) / this may cause problem no or partial
output /
13Synchronization
- pthread_join(that_thread, status)
- wait until that_thread completes
- read man for the meaning of status (the
return value of the terminating thread) - mutex (mutual exclusion) - dynamic creation
- pthread_mutex_t mutexp
- mutexp (pthread_mutex_t )malloc(sizeof(pthread_
mutex_t)) - pthread_mutex_init(mutexp, NULL)
- pthread_mutex_lock(mutexp)
- mutex - static creation
- pthread_mutex_t xxx PTHREAD_MUTEX_INITIALIZER
- pthread_mutex_lock(xxx)
- pthread_mutex_destroy(mutex)
- can be used for inter-process communications
14Synchronization (contd)
- int pthread_mutex_trylock(mutex)
- do not block the calling thread
- useful for polling
- checking IO status
- avoid deadlock, priority inversion
- review of mutex
- most popular primitives
- easy to use
- easy to understand what it is
- prone to errors
- programmers forget to unlock
- what if another thread forgets to use lock
- very difficult to understand programs that
contain it
15Semaphore
- why semaphore
- mutex may result in busy-waiting
- mutex is only for mutual exclusion - no sharing
- no guarantee of fairness
- semaphore
- a shared variable with two attributes
- integer value number of threads that can share
this semaphore - allows n threads to share
- thread list list of threads waiting for this
semaphore - guarantees FIFO order
- operations
- cc flag ... file ... -lposix4 library ...
/ lib for real time extension / - include ltsemaphore.hgt
- int sem_init(sem_t sem, int pshared,
unsigned int value ) - pshared if non-zero, it is shared between
processes - i.e., zero means that it will be used between
threads
16Semaphore(contd)
- int sem_wait(sem_t sem) int
sem_trywait(sem_t sem) - if the integer value gt 0, decrement it and
proceeds - else block (or fail for trywait)
- int sem_post(sem_t sem)
- if there is a thread waiting,
- wake up a thread according to its schedparam
- ptread_attr_setschedparm()
- else increment the integer value
- int sem_destroy(sem_t sem)
- other combination
- sem_open(), sem_close()
17Producer/Consumer using mutex
- void consumer_function(void)
-
- while(1)
-
- pthread_mutex_lock( mutex )
- if ( buffer_has_item 1)
-
- consume_item( buffer )
- buffer_has_item 0
-
- pthread_mutex_unlock( mutex )
- pthread_delay_np( delay )
-
-
void producer_function(void) while(1)
pthread_mutex_lock( mutex )
if ( buffer_has_item 0 )
buffer make_new_item()
buffer_has_item 1
pthread_mutex_unlock( mutex )
pthread_delay_np( delay )
18Producer/Consumer using semaphore
void consumer_function(void)
while(1) semaphore_down(
readers_turn ) consume_item( buffer
) semaphore_up( writers_turn )
void producer_function(void) while(1)
semaphore_down( writers_turn )
buffer make_new_item()
semaphore_up( readers_turn )
19Programming Models
- Master/Slave
- socket program example
- thread is created on the fly
- work queue model
- the work queue contains a bag of works
- a set of worker threads are created a priori
- each thread does the following until done
- competes to fetch a work from the queue
- compute on the work
- generate another work, if any
- insert the new work into the queue
- threads created a priori
- if they are too many, there would be idle threads
- a waste - if they are too few, not enough concurrency to
carry the work - solution
- prepare some threads a priori and create(and
kill) more threads as necessary
20Thread Canceling
- why does a thread need to be cancelled
- a transaction all or nothing
- pthread_cancel(pid)
- a cancelled thread needs to be joined (zombie!)
- detached threads do not need to be joined
- thread types about cancellation
- pthread_setcanceltype(type, NULL)
- PTHREAD_CANCEL_ASYNCHRONOUS cancel ASAP
- PTHREAD_CANCEL_DEFERRED deferred until cancel
point - cancel points
- pthread_testcancel()
- pthread_join(), pthread_cond_wait(), sem_wait()
- uncancelable thread
- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,
NULL) - use it inside a critical section
21Thread-Specific Data
- threads belong to the same process(address space)
- share all the data
- weak protection for the shared data
- Linux provides a space for data private to a
thread - each item should be created associated with a key
- static pthread_key_t test_key
- pthread_key_create (test_key, clean_up)
- pthread_setspecific (test_key, data_to_store)
/ write / - data_to_read pthread_getspecific (test_key) /
read / - when a thread exits, clean_up is called
- clean up can be installed without thread-specific
data - prevents memory leak
- clean up function is called when a thread exits
22clean up example
void allocate_buffer (size_t size) return
malloc (size) void deallocate_buffer (void
buffer) free (buffer) void do_some_work
() void temp_buffer allocate_buffer
(1024) pthread_cleanup_push
(deallocate_buffer, temp_buffer) / Do some
work here that might call pthread_exit or might
be cancelled... / / Unregister the cleanup
handler. Because we pass a nonzero value, this
actually performs the cleanup by calling
deallocate_buffer. / pthread_cleanup_pop
(1)