# Chapter 2 Managing Threads
## Disclaimer
This is my personal notes of the [C++ Concurrency in Action, Second Edition](https://www.manning.com/books/c-plus-plus-concurrency-in-action-second-edition) book. Most ideas come from the book.
## Basic Usage
Normally, we start a thread in C++ by `std::thread(work_func, arg1)` and then wait for it to complete with `join`. If we don't call `join`, the main thread will complete before the `t` thread, and `t` will be handled by OS. The example below also shows how to pass arguments to thread by value. The integer `num` is **copied** to the thread's own address space.
```C++
#include <thread>
#include <iostream>
void work_func(int num)
{
std::cout << "Intensive work " << num << std::endl;
}
int main()
{
std::thread t(work_func, 10);
t.join();
}
```
If we don't want to wait for the thread to finish, we can call `detach`. Then, the thread will be classified as daemon thread, which typically run long-time background work.
```C++
#include <thread>
#include <iostream>
void work_func(int num)
{
std::cout << "Intensive work " << num << std::endl;
}
int main()
{
std::thread t(work_func, 10);
// t.join();
t.detach();
}
```
## Pass reference to thread
Suppose the worker function requires reference as arguments, we would need `std::ref` to accomplish this. In following example, we use assert to check if the number is correctly incremented.
```C++
#include <thread>
#include <cassert>
void work_func(int& num)
{
num++;
}
int main()
{
int local = 10;
std::thread t(work_func, std::ref(local));
// std::thread t(work_func, local); <-- will throw error
t.join();
assert(local == 11);
}
```
## Move data to thread
If the arguments can only be **moved** but not **copied**, we need to use `std::move` to move the object to the thread's local storage. The following example also shows that we can use `std::this_trhread::get_id()` to get the thread id. It is useful for us to identify thread when we manages threads with `std::vector<std::thread>`.
```C++
#include <thread>
void work_func(std::unique_ptr<int> num_ptr)
{
(*num_ptr)++;
std::cout << "Thread: " << std::this_thread::get_id() << ", Value: " << *num_ptr << std::endl;
}
int main()
{
std::unique_ptr<int> local = std::make_unique<int>(10);
std::thread t(work_func, std::move(local));
t.join();
}
```
## Use with member function
The first argument of `std::thread` will be the **reference** to the class's method. Note that for non-member function, we do not need to explicitly pass reference to function to `std::thread`. The second argument is the object pointer, where the memeber function will be called on this object. The later arguments will be the arguments of the member function.
```C++
#include <thread>
#include <cassert>
class Worker
{
public:
void work_func(int& num)
{
num++;
}
};
int main()
{
int local = 10;
Worker w;
std::thread t(&Worker::work_func, w, std::ref(local));
t.join();
assert(local == 11);
}
```
## Follow-up reading in this chapter
- `joining_thread` with **RAII**(Resource Acquisition Is Initialization)
- naive parallel version of `std::accumulate`
## About Me
A self-motivated programmer who is exploring low-latency C++.
>Personal Website: https://jacky-chen-portfolio.vercel.app/
>GitHub: https://github.com/TypeErrorEngine2022
>Email: jackychenworkcontact@gmail.com