Professional Documents
Culture Documents
Programming With Threads
Programming With Threads
CS 475
This lecture is based upon Sections 13.3-8 of Computer Systems: A Programmerʼs Perspective
by Bryant & OʼHalloran
– 2 – CS 475
Page 1
Threads Memory Model
– 3 – CS 475
– 4 – CS 475
Page 2
Mapping Variables to Mem. Instances
Global var: 1 instance (ptr [data])
– 6 – CS 475
Page 3
badcnt.c: An Improperly
Synchronized Threaded Program
unsigned int cnt = 0; /* shared */ /* thread routine */
void *count(void *arg) {
int main() { int i;
pthread_t tid1, tid2; for (i=0; i<NITERS; i++)
Pthread_create(&tid1, NULL, cnt++;
count, NULL); return NULL;
Pthread_create(&tid2, NULL, }
count, NULL);
linux> ./badcnt
Pthread_join(tid1, NULL); BOOM! cnt=198841183
Pthread_join(tid2, NULL);
linux> ./badcnt
if (cnt != (unsigned)NITERS*2) BOOM! cnt=198261801
printf("BOOM! cnt=%d\n",
cnt); linux> ./badcnt
else BOOM! cnt=198269672
printf("OK cnt=%d\n",
cnt); cnt should be
} equal to 200,000,000.
What went wrong?!
– 7 –
CS 475
– 8 – CS 475
Page 4
Concurrent Execution
– 9 – CS 475
– 10 – CS 475
Page 5
Concurrent Execution (cont)
– 11 – CS 475
Progress Graphs
Thread 2
A progress graph depicts
the discrete execution
state space of concurrent
T2
threads.
(L1, S2)
Each axis corresponds to
S2
the sequential order of
instructions in a thread.
U 2
Each point corresponds to
a possible execution state
L2
(Inst1, Inst2).
– 12 – CS 475
Page 6
Trajectories in Progress Graphs
Thread 2
A trajectory is a sequence
of legal state transitions
T2
that describes one possible
concurrent execution of
the threads.
S2
Example:
U 2
H1, L1, U1, H2, L2,
S1, T1, U2, S2, T2
L2
H 2
Thread 1
H 1
L1
U 1
S1
T1
– 13 – CS 475
S2
Instructions in critical
sections (wrt to some
critical shared variable) should
section U 2
Unsafe region
not be interleaved.
wrt cnt
Sets of states where such
L2
interleaving occurs
form unsafe regions.
H 2
Thread 1
H 1
L1
U 1
S1
T1
– 14 – CS 475
Page 7
Safe and Unsafe Trajectories
Thread 2
T2
Safe trajectory
Def: A trajectory is safe
iff it doesnʼt touch any
S2
Unsafe region
Unsafe
part of an unsafe region.
trajectory
critical Claim: A trajectory is
section U 2
correct (wrt cnt) iff it is
wrt cnt
safe.
L2
H 2
Thread 1
H 1
L1
U 1
S1
T1
– 15 – CS 475
Semaphores
– 16 – CS 475
Page 8
Safe Sharing with Semaphores
/* Semaphore s is initially 1 */
/* Thread routine */
void *count(void *arg)
{
int i;
– 17 – CS 475
Page 9
POSIX Semaphores
/* Initialize semaphore sem to value */
/* pshared=0 if thread, pshared=1 if process */
void Sem_init(sem_t *sem, int pshared, unsigned int value) {
if (sem_init(sem, pshared, value) < 0)
unix_error("Sem_init");
}
– 19 – CS 475
if (cnt != (unsigned)NITERS*2)
printf("BOOM! cnt=%d\n", cnt);
else
printf("OK cnt=%d\n", cnt);
exit(0);
}
– 20 –
CS 475
Page 10
Signaling With Semaphores
producer
shared
consumer
thread
buffer
thread
– 21 – CS 475
Producer-Consumer on a Buffer
That Holds One Item
/* buf1.c - producer-consumer int main() {
on 1-element buffer */ pthread_t tid_producer;
#include “csapp.h” pthread_t tid_consumer;
exit(0);
}
– 22 – CS 475
Page 11
Producer-Consumer (cont)
Initially: empty = 1, full = 0.
– 23 – CS 475
Thread Safety
– 24 – CS 475
Page 12
Thread-Unsafe Functions
– 25 – CS 475
– 26 – CS 475
Page 13
Thread-Unsafe Functions (cont)
struct hostent
*gethostbyname(char name)
{
static struct hostent h;
<contact DNS and fill in h>
return &h;
}
hostp = Malloc(...));
gethostbyname_r(name, hostp);
struct hostent
*gethostbyname_ts(char *p)
{
struct hostent *q = Malloc(...);
P(&mutex); /* lock */
p = gethostbyname(name);
*q = *p; /* copy */
V(&mutex);
return q;
}
– 27 –
CS 475
Thread-Unsafe Functions
– 28 – CS 475
Page 14
Reentrant Functions
All functions
Thread-safe
functions
Thread-unsafe
functions
Reentrant
functions
– 29 – CS 475
– 30 – CS 475
Page 15
Races
/* thread routine */
void *thread(void *vargp) {
int myid = *((int *)vargp);
printf("Hello from thread %d\n", myid);
return NULL;
– 31 –
} CS 475
Deadlock
Locking introduces the
Thread 2
potential for deadlock:
V(s)
deadlock
waiting for a condition that
forbidden
state
will never be true.
region for s
Any trajectory that enters
V(t)
the deadlock region will
eventually reach the
deadlock state, waiting for
P(s)
either s or t to become
deadlock
forbidden
nonzero.
region
region for t
P(t)
Other trajectories luck out
and skirt the deadlock
region.
Page 16
Threads Summary
– 33 – CS 475
Page 17