Escolar Documentos
Profissional Documentos
Cultura Documentos
Basics
Computer Systems Organization (Spring 2016)
CSCI-UA 201, Section 2
Concurrency (Review)
Multiple logical control flows.
Flows run concurrently if they overlap in time
Otherwise, they are sequential
Why: efficiency
Due to power wall cores are not getting faster, just more numerous
To speed up programs using multiple CPUs we have to write concurrent code.
From systems perspective, dont idle CPU while IO is performed
To speed up programs the system interleaves CPU processing and I/O.
Thread-based
Kernel automatically interleaves multiple logical flows
Each flow shares the same address space
Threads are less expensive for the system!
Process-based Concurrency
int numbers[1000];
int sum1 = 0;
int sum2 = 0;
void
main()
{
pid_t pid = fork();
assert(pid >= 0);
if (pid != 0) {
for (int i = 0; i < 500; i++) {
sum1 += numbers[i];
}
} else {
for (int i = 0; i < 500; i++) {
sum2 += numbers[500+i];
}
return;
}
waitpid(pid, NULL, 0);
printf("sum is %d\n", sum1+sum2);
}
Interprocess Communication
How to communicate across processes? (inter-process communication
or IPC)
via sockets
via pipes
via shared memory objects
Unix Pipes
Unlike other forms of interprocess communication, a pipe is one-way
communication only (there are duplex options, but those are not typically
supported)
Via a pipe, output of one process is the input to another process.
Pipes in C
The pipe system call is called
with a pointer to an array of
two integers.
The first element of the array
contains the file descriptor that
corresponds to the output of
the pipe
The second element of the
array contains the file
descriptor that corresponds to
the input of the pipe.
int fd[2];
pipe(fd);
10
ls | grep ".c"
11
Cons
Can be confusing quickly in non-trivial programs
Processes using pipes must have a common parent process
( hmm ??? so why do they work in the terminal)
Uni-directional
Little capability for error handling
Requires system call
12
Shared Memory
Shared Memory is an efficient means of passing data between
programs.
Allow two or more processes access to the same address space
for reading and writing.
A process creates or accesses a shared memory segment using
shmget()
Example of two processes using shared memory
shared_memory_server.c
shared_memory_client.c
13
Cons
Error prone, difficult to debug
Requires system call
All the same synchronization problems as threads (which we will
understand soon!)
14
Cons
Systems calls necessary
Nontrivial to share data between processes
Requires IPC (interprocess communication) mechanisms
15
Thread-based Concurrency
16
What is a Thread?
A thread is
a unit of execution, associated with a process.
the smallest sequence of instructions that can be managed independently by
the OS scheduler
(it is NOT a separate process)
17
Process context
Program context:
Registers
Condition codes
Stack pointer (SP)
Program counter (PC)
Kernel context:
VM structures
File descriptors
brk pointer
SP
Shared libraries
brk
Run-time heap
Read/write data
Read-only code/data
PC
0
18
Thread context
Shared libraries
SP
Stack
Thread context:
Registers
Condition codes
Stack pointer (SP)
Program counter (PC)
brk
Run-time heap
Read/write data
Read-only code/data
PC
0
Kernel context:
VM structures
File descriptors
brk pointer
19
Data registers
Condition codes
SP1
PC1
stack 2
run-time heap
read/write data
read-only code/data
Thread 2 context:
Data registers
Condition codes
SP2
PC2
Kernel context:
VM structures
Descriptor table
brk pointer
20
Process hierarchy
P0
T2
T4
T1
P1
sh
T5
sh
sh
T3
foo
bar
21
Concurrent Threads
Two threads are concurrent if their flows overlap in time
Otherwise, they are sequential
Examples:
Concurrent: A & B, A&C
Sequential: B & C
Thread A
Thread B
Thread C
Time
22
Thread A
Thread B
Thread A
Thread C
Thread B
Thread C
Time
23
Differences
Threads share all code and data (except local stacks)
Processes do not
Threads are somewhat less expensive than processes
Process control (creating/reaping) more expensive than thread control
24
/*
* hello.c - pthreads "hello, world" program
*/
void *thread(void *vargp);
int main()
{
pthread_t tid;
pthread_create(&tid, NULL, thread, NULL);
pthread_join(tid, NULL);
exit(0);
}
Thread ID
Thread attributes
(usually NULL)
Thread routine
Thread arguments
(void *p)
Return value
(void **p)
26
call pthread_create()
pthread_create() returns
Peer thread
call pthread_join()
printf()
Main thread waits for
peer thread to terminate
return NULL;
Peer thread
terminates
pthread_join() returns
exit()
Terminates
main thread and
any peer threads
27
28
Race Example
int numbers[2] = { 1, 1 };
int sum = 0;
int main()
{
pthread_t tid;
pthread_create(&tid, 0, run, (void *)(numbers + 1));
for (int i = 0; i < 1; i++)
sum += numbers[i];
}
pthread_join(tid, 0);
Cons
Unintentional sharing can introduce subtle and hard-to-reproduce errors.
Hard to detect by testing since probability of bad outcome can be low
31
Thread-based
32