Synchronization 1: Threads and atomicity

Overview

In this lecture, we discuss multithreading, low-level synchronization, and synchronization objects.

Full notes on synchronization

Update on racer programs

Multitasking, multiprocessing, multithreading

Example threads

#include <cstdio>
#include <thread>

void threadfunc1() {
    printf("Hello from thread 1\n");
}

void threadfunc2() {
    printf("Hello from thread 2\n");
}

int main() {
    std::thread t1(threadfunc1);
    std::thread t2(threadfunc2);
    t1.join();
    t2.join();
}

Thread functions can take arguments

#include <cstdio>
#include <thread>

void threadfunc(int n) {
    printf("Hello from thread %d\n", n);
}

int main() {
    std::thread t1(threadfunc, 1);
    std::thread t2(threadfunc, 2);
    t1.join();
    t2.join();
}

Threads run concurrently

Processes vs. threads

Detached threads

Advantages of threads for synchronization

A toy task

What?!

incr-basic-noopt

Data races

The Fundamental Law of Synchronization

THOU SHALT NOT HAVE DATA RACES!!!

Explicit synchronization

Atomic operations

addl $0x1,(%rdi)

Atomic instructions

incr-atomic.cc

Mutual exclusion

std::mutex

incr-mutex.cc

std::scoped_lock

Question

incr-spinlock.cc