Title: Threads Part 2
1Threads Part 2
2Concurrency
- there are many situations where parallel
programming is useful - Clear trend towards duo-core and multi-core
machines - Servers handle multiple clients simultaneously
- User interface handle user input during
processing
3POSIX Threads
- A standard library of functions to help create
and manage threads pthreads - create a thread
- include ltpthread.hgt
- int
- pthread_create(pthread_t thread_id,
- const pthread_attr_t
attributes, - void (thread_function)(void
), - void arguments)
4POSIX Threads
- exit a thread when the thread function returns or
calls pthread_exit() - wait for a thread to terminate
- include ltpthread.hgt
- int
- pthread_join(pthread_t thread_id,
- void status_ptr)
5Function Pointers
- These are pointers, i.e. variables, which point
to the address of a function - This is useful if you can only decide which
function to call at run-time (called
late-binding) - Note A function pointer always points to a
function with a specific signature! - Thus all functions, you want to use with the same
function pointer, must have the same parameters
and return-type!
6include ltstdio.hgt include ltstring.hgt int
add(int a, int b) int del(int a, int b) int
test_op(int (op)(int , int ), int op1, int
op2) int main() char choice int a,
b printf("Enter the op you want (a - add d
- del)gt ") scanf("c",choice)
printf("Enter the two operandsgt")
scanf("dd",a, b) switch (tolower(choice))
case 'a' printf("d d
d\n",a,b,test_op(add,a,b))
break case 'd' printf("d - d
d\n",a,b,test_op(del,a,b))
break default printf("invalid
option\n") break
int add (int a, int b) return (a
b) int del (int a, int b) return (a
- b) int test_op (int (op)(int a, int b),
int op1, int op2) return op(op1,op2)
Example
7Simple Thread Example
8/ http//www.yolinux.com/TUTORIALS/LinuxTutorial
PosixThreads.html / include ltstdio.hgt include
ltstdlib.hgt include ltpthread.hgt void
print_message_function( void ptr ) main()
pthread_t thread1, thread2 char
message1 "Thread 1" char message2
"Thread 2" int iret1, iret2 /
Create independant threads each of which
will execute a function / iret1
pthread_create( thread1, NULL,
print_message_function, (void) message1)
iret2 pthread_create( thread2, NULL,
print_message_function, (void)
message2)
9/ Wait till threads are complete before
main continues. Unless we wait we run the
risk of executing an exit which will
terminate the process and all threads
before the threads have completed.
/ pthread_join( thread1, NULL)
pthread_join( thread2, NULL)
printf("Thread 1 returns d\n",iret1)
printf("Thread 2 returns d\n",iret2)
exit(0) void print_message_function( void
ptr ) char message message (char
) ptr printf("s \n", message)
To compile gcc pthread1.c -lpthread
10Thread problems Sharing memory
- /thread 1/
- a data
- a
- data a
- /thread 2/
- b data
- b--
- data b
If these threads are executed sequentially (eg 1
followed by 2) then the final value of data is
predictable
11Thread problems Sharing memory
If the threads are interleaved
- /thread 1/
- a data
- ..
- a
- ..
- data a
- /thread 2/
- ..
- b data
- ..
- b--
- ..
- data b
12Thread problems
- There is no way to predict the final value of
data. - The value could be 1, 0 or -1!
- On multiprocessor machines where several
processors have access to the memory, the result
may even be completely scrambled as the
processors compete for the memory location of
data - We need to be able to synchronise the threads
somehow.
13Mutual Exclusion
- Mutual exclusion refers to a technique that
ensures that only a single thread is executing a
specified section of program code at any
particular time. - A mutex is a form of lock that must be controlled
by a thread before it is allowed to proceed - A thread locks a section before it enters and
unlocks it when it is finished
14Pthreads mutex
- Initialise a mutex lock
- int pthread_mutex_init(pthread_mutex_t mut,
const pthread_mutexattr_t attr) - Acquire a lock
- int pthread_mutex_lock(pthread_mutex_t mut)
- Unlock
- int pthread_mutex_unlock(pthread_mutex_t mut)
- Try a lock
- int pthread_mutex_trylock(pthread_mutex_t mut)
- Destroy a lock
- int pthread_mutex_destroy(pthread_mutex_t mut)
15Mutex example
- /thread 1/
- pthread_mutex_lock(mut)
- ..
- a data
- a
- data a
- pthread_mutex_unlock(mut)
- /thread 2/
- ..
- pthread_mutex_lock(mut)
- ..
- ..
- ..
- ..
- b data
- b--
- data b
- pthread_mutex_unlock(mut)
16Mutex problems
- Programs that use mutex locks to control access
to critical sections of code can suffer from
deadlock! - Deadlock can occur in a number of ways
- Eg two threads are each waiting on locks held by
the other - Thread 1 acquires lock A
- Thread 2 acquires lock B
- Thread 1 wants lock B
- Thread 2 wants lock A
17Mutex problems
- Another problem that can occur are race
conditions - A thread may not acquire the correct lock, enters
a critical section and modifies some data
structure giving inconsistent results - You need to be very careful when programming with
threads, such that functions you call are
thread-safe - Often, the documentation of library functions
will state if they are thread safe
18Acknowledgement
- Lecture prepared by Bob Kummerfeld.
- The code example in this lecture comes from
- http//www.yolinux.com/TUTORIALS/LinuxTutorialPosi
cThreads.html