11 - Concurrency and Threads

Class: CSCE-313


Notes:

Outline:

  1. What is concurrency?
    • Macro illusion that multiple things are happening at the same time
  2. What is a thread?
    • A useful abstraction for a program to program in a concurrent world
  3. Thread context switch
  4. Thread API

What is concurrency?

...

Notes:

What is a thread?

...

Notes:

Threads as a programmatic framework

...

Multi-threaded process

...

Notes:

Process vs. Thread

Notes:

Motivation for Threads

Basically two reasons:
...

Notes:

Process Context Switch

Notes:

Thread Context Switch

Notes:

Thread-based applications

...

Notes:

Threaded web server

...

Notes:

Thread Execution

...

Notes:

Problem with shared addresses-I

...

Notes:

The race condition problem

...

Notes:

Rate condition in Assembly

...

Notes:

Race condition may happen because of instruction reordering

...

Notes:

Out-of-Order Execution causing Race Condition

image-26.png502

Notes:

pthread (POSIX thread) creation

With pthreads, when a program runs, it also starts out as a single process with a single thread of control.

The pthread_create() function starts a new thread in the calling process.

#include <pthread.h>
int pthread_create(pthread_t *tid, const pthread_attr_t *attr,
    void *(*func) (void *), void *arg);

pthread_create returns 0 if successful, a positive error code if not.

C++ Thread API

#include <iostream>
#include <thread>
#include <unistd.h>
using namespace std;

void foo() {
    sleep(3);
    cout << "foo done" << endl;
}
void bar(int x) {
    sleep(1);
    cout << "bar done" << endl;
}

int main() {
    thread foothrd(foo); // calls foo() in a thread
    thread barthrd(bar, 77); // calls bar(x) in a thread
    cout << "main, foo and bar would now execute concurrently..." << endl;
    
    foothrd.join(); // pauses until foo finishes
    barthrd.join(); // pauses until bar finishes
    cout << "foo and bar completed." << endl;
    return 0;
}

Output:

maon, foo, bar, fib execute concurrently ...
bar: received 77
foo: done
foo, bar, fib completed

Race Condition Demonstration

#include <iostream>
#include <thread>
#include <unistd.h>
using namespace std;

void func(int *p, int x) {
    // increment *p x times
    for (int i = 0; i < x; i++)
    *p = *p + 1;
}

int main(int ac, char **av) {
    int data = 0;
    int times = atoi(av[1]);
    // start 2 threads to increment
    thread t1(func, &data, times);
    thread t2(func, &data, times);
    t1.join();
    t2.join();
    cout << "data=" << data << endl;
    return 0;
}
root@ubuntu-csce313:~\# g++ race-condition.cc root@ubuntu-csce313:~\# ./a.out 100000 data=200000
root@ubuntu-csce313:~\# ./a.out 1000000 data=2000000
root@ubuntu-csce313:~\# ./a.out 10000000 data=10938339
root@ubuntu-csce313:~\# ./a.out 10000000 data=14035068
root@ubuntu-csce313:~\# ./a.out 10000000 data=17764839
root@ubuntu-csce313:~\# ./a.out 10000000 data=16256394
root@ubuntu-csce313:~\# ./a.out 10000000 data=14049964