1/249
Looks like no tags are added yet.
Name | Mastery | Learn | Test | Matching | Spaced |
|---|
No study sessions yet.
multithreading
multiple tasks in one program
multitasking
multiple processes in a program (fork/exec/wait)
what is the problem with multitasking using processes?
being separate is safe but coordination is difficult, need to communicate between processes to update data
what is the main difference with multithreading
shared access to mutable data
pthread_t
thread identifier (TID), integer value
pthread_t pthread_self (void)
returns TID of the calling thread
int pthread_create(
pthread_t *tid,
pthread_attr_t *attr,
void (thread_fun) (void *),
void *arg
);
tid -> OUTPUT: TID of created thread
attr ->INPUT: additional features for thread, use NULL for default
thread_fun -> function thread will execute
arg -> arguments to pass to thread
int pthread_join (
pthread_t tid,
void **rval
);
retrieves return value of specified thread, blocks if thread has not yet terminated
tid -> tid of thread we are joining too
rval -> void pointer returned by thread, need to cast to check value
int pthread_detach (pthread_t tid);
makes thread unjoinable (cleans up after itself)
main difference between processes and threads?
processes have clear parent-child relationship, while all threads are peers
non determinism
outcome/behavior of program is not solely determined by input
race conditions
occurs whenever a programs behavior is determined by external timing
non critical race condition
different behavior, same outcome (we don't need to worry)
critical race condition
different outcome
data races require three conditions
1) shared mutable data
2) accessed by multiple threads, without coordination
3) at least one thread modifies the data
why do we need to worry about data races?
no guarantee of what happens in programs that have them, especially bad in real world applications like banking
sequential consistency
model of memory where all accesses can be placed in some consistent order (every read happens before or after a given write, NOT during)
how to prevent data races?
coordinate use of shared data
memory fences
pause operation on a CPU until all writes have completed
EXPERT LEVEL for efficiency
atomic instructions
an instruction modify some memory location so all memory accesses are strictly before or after
operations are performed as a single invisible step, so no overlap
test-and-set instruction
set a value to 1 and returns its previous value, atomic instruction
compare-and-swap
set a value in memory and return whether it had expected value, only modify value if its the same
critical sections
parts of code changing shared data, we want all access to data to be in a critical section to for sequential access
pthread_mutex_t
opaque data structure, must not be copied
create new pthread_mutex_t m
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
int pthread_mutex_init (pthread_mutex_t mut, pthread_mutexattr_t attr);
mut -> pthread_mutex_t lock
attr -> use NULL for default options
int pthread_mutex_destroy (pthread_mutex_t *mut)
destroy a lock (typically at end of program)
int pthread_mutex_lock (pthread_mutex_t *mut)
acquire the mutex lock, if another thread has mutex, block until that thread releases, then we can access critical section
int pthread_mutex_unlock (pthread_mutex_t *mut)
release mutex, only thread that has mutex can unlock it
if any threads were waiting, activate the one waiting the longest
condition variable
block a thread until a condition is met
pthread_cond_t
opaque data structure, shouldn't be copied
always associated with a mutex
int pthread_cond_init (pthread_cond_t cond, pthread_condattr_t attr)
create condition pthread, attr is NULL for default values
int pthread_cond_destroy (pthread_cond_t *cond);
destroy condition lock
int pthread_cond_wait (pthread_cond_t cond, pthread_mutex_t mut);
we must currently hold mut, block calling thread after unlocking mut
block until condition is true
int pthread_cond_signal (pthread_cond_t *cond);
tells one thread waiting for condition to proceed
int pthread_cond_broadcast (pthread_cond_t *cond);
tells all threads waiting for condition to proceed
when does a thread end?
when its starting function returns, then we detach it
OR when it calls pthread_exit()
what happens when exit() is called in a thread?
terminates all threads
int pthread_kill (pthread_t target, int signal_number);
sends a signal to specified thread
how to handle blocking signals with multiple threads?
use pthread_sigmask() instead of sigprocmask()
block signal in creator thread, create new thread, then unblock signal to let new thread inherit disposition
deadlock
situtation that can arise with multiple communicating processes where no process can make progress
necessary conditions for deadlock
1) mutual exclusion
2) hold and wait - block waiting for a resource while holding another
3) no preemption - cant force a thread to release a resource
4) circular wait - each thread is waiting for a resource held by another in a cycle
to avoid a deadlock
ensure at least one condition is not satisfied
semaphores
non-negative integer that we either increment or decrement
increment / post
increases value of semaphore by 1
if semaphore was 0, wakes up 1 thread
decrement / wait
decreases value of semaphore by 1
if semaphore is zero, blocks until another thread calls post
how is mutex a semaphore?
starting value 1
lock -> wait
unlock -> post
process group
a set of one of more processes identified by PID
process group leader
if process is running with the same PID as PGID
session
one or more process groups, usually associated with login session or a terminal, identified by session ID
network communication
inter-process conmmunication, processes may be hosted on different computers
link
direct connection between two devices/hosts
network
collection of hosts that can communicate, directly or indirectly
internetwork
two or more connected networks
circuit switching
communication resources are dedicated to a particular session, guaranteed quality but consumes a lot of bandwidth
packet switching
messages come in discrete units, not a continuous stream (packets, frames) more efficient and less expensive, messages may have to be split up for travel
latency
length of time between transmission and receipt
throughput
how many bits we can transmit per second
application layer
send messages among different hosts
network layer
routes messages between indirectly connected hosts, find a route to enable message arrival
link layer
transmits messages between directly connected hosts
internet protocol (ip)
best-effort, packet-switched, connection-less protocol
5 layer practical networking framework focusing on data being transmitted
OSI
7 layer conceptual framework, each layer has clearly defined function and works independently of otheres
what are the five layers of internet protocol?
application, transport, network, data link, physical
what are the three layers in osi that correspond to ip's application layer?
session, presentation, application
best effort
no guarantee data is effectively delivered or that delivery meets quality of service
how many bits does an IPv4 address have?
32 bits
how many bits does an IPv6 address have?
128 bits
ip addresses are used
to help routing from indirectly connected hosts
subnet mask
how many bits belong to the network
192.168.1.0/24 -> first 24 bits are network, last 8 are host
what are the two methods of the transport layer in ip?
udp, tcp
udp (user datagram protocol)
no guarantee packets will arrive or be in correct order but very fast
tcp (transmission control protocol)
provides reliable, ordered, and error-checked delivery of a stream of packets on the internet, need to establish reliable TCP connection before sending data
domain name service (DNS)
internet directory service that allows devices and services to be named and discoverable
domain
sequence of names separated by dots, each name is controlled by someone who assigns subdomains
sockets
api for network communication (part of posix library)
int sock(int domain, int socket_type, int protocol);
domain -> network we are using
socket_type -> what sort of socket are we creating
protocol -> additional flags
domain in socket
AF_INET -> v4
AF_INET6 -> v6
socket type in socket function
SOCK_DGRAM -> datagrams (connectionless, unreliable)
SOCK_STREAM -> streaming connection (connection-oriented, reliable)
connectionless communication
data transmission method using data packets by addressing data packet to new destination
connection-oriented communication
establish a connection before transferring any data
socket returns
file descriptor used to reference socket on success
-1 and sets errno on failure
int connect (int socketfd, struct sockaddr *remote_addr, socklen_t remote_addr_len);
establish a connection to a remote host accepting incoming connection
socketfd -> socket we are using to connect
remote_addr ->address(host:port) of remote end
remote_addr_len -> sizeof(remote_addr)
connect returns
0 on success, -1 on failure
bind()
associate socket with port number
listen()
put socket into passive mode and wait for incoming connections
connect()
establish connection with running socket
datagram endpoint
send and recieve datagram packets
listening socket
used for connection-oriented sockets (TCP), wait for incoming connection (establish path)
connection socket
one end of connection
nimd program structure
create listening socket in openListener and return connection from client
create connection socket using accept()
send data using send() function
signals
send asynchronous messages to processes
disposition for a signal
what happens when that signal is recieved
possible dispositions
ignore, terminate, stop, continue, run signal handler
how do dispositions carry over from fork()
inherited in child process
how are dispositions handled using exec()
preserved in running program except for handler functions
kill
sends SIGTERM to specified process
kill - [NAME]
sends SIGNAME to specified process
kill -KILL
sends SIGKILL to specified process
int sigaction (int signumber, const struct sigaction new, struct sigaction old);
signal type, new disposition, old disposition is written to old