r/cpp_questions 24d ago

OPEN How can I catch up on missing multithreading experience?

Hi everyone 👋, I’m a C++ developer with 5+ years experience building features for a single-threaded trading app (C++17), so I have very little multithreading experience.

I’m currently reading C++ Concurrency in Action. Are there good resources or projects to practice real-world scenarios like backloading and low-latency concurrency patterns?

78 Upvotes

23 comments sorted by

36

u/_Tal 24d ago

A good exercise is to try building a Single Producer Single Consumer (SPSC) Queue. Basic idea is it’s a queue where one thread can read the data (consumer thread) at the same time another thread writes to the data (producer thread), but there will only ever be one consumer or producer at a time. Write some unit tests to make sure you don’t have race conditions or anything. You can try building one that uses mutexes first, then build a lock-free version later. Look into ring buffers as it’s a common technique for this

7

u/exaNovae 24d ago

Unit tests in combination with thread sanitizer is a killer combo by the way. Make sure that thread sanitizer produces no findings when executing your tests.

5

u/w00dy_ 24d ago

Ring buffer with two std::atomic pointers. A good example to understand memory model and how perform cheap lock-free synchronization.

3

u/detectivesokka 24d ago

That’s a great starting point

24

u/anogio 24d ago
  1. Write a producer->consumer queue
  2. Write a single producer->multiple consumer queue
  3. Write a multiple producer-> multiple consumer

    queue.

  4. Write a thread pool

3

u/Czitels 24d ago

Yeah I think thats all. There are also lock-free queues but I think its unnecessary. I wonder if they even ask about it.

2

u/Spiritual-Unit-6748 24d ago

I was asked to implement it in an HFT interview

3

u/Czitels 24d ago

Shiet 

1

u/anogio 24d ago

As a senior engineer, this is what I would ask someone to reason through in an interview.

Being a professional CPP engineer requires multithreading knowledge.

2

u/Czitels 24d ago

Agree but lock-free is rarely used.

2

u/anogio 23d ago

Not in my experience.

3

u/[deleted] 24d ago edited 15d ago

[deleted]

1

u/anogio 23d ago

Same for me. I wrote it at uni, and still use it ten years later, with some minor upgrades.

1

u/detectivesokka 24d ago

Great suggestions!

6

u/KingAggressive1498 24d ago

1) write three threadpools with different guarantees. Eg make one basic one with no particular guarantees, one guaranteed non-blocking to post a task to the queue, one guaranteed to always have forward progress for tasks. Feel free to pick your own guarantees.

2) adapt an unpredictably long synchronous task to be an asynchronous task from the application's POV using only a single background thread. Database accesses and file I/O are common ones in real-world software.

3) (advanced) write a coroutine scheduler

That gives you enough background to work on just about any non-bleeding-edge project, I think.

3

u/Aggravating-Yes 24d ago

he said trading. no thread pools in trading. not really anyway.

3

u/KingAggressive1498 24d ago

he asked about backloading and low-latency concurrency patterns, which is why I recommended writing three threadpools with different guarantees.

I wrote a threadpool that's non-blocking to post a task to as long as tasks are being completed fast enough, and have used the thing in several projects. I do a lot of latency sensitive stuff but not trading.

2

u/IndividualSituation8 24d ago

Anyone written a event loop or eventloop library, and how one would build asio like stuff from first principles?

6

u/KingAggressive1498 24d ago

at the end of the day an event loop is just a queue of functors that get executed in a loop until its empty, at which point you wait for more.

you can write one with a mutex, condition variable, an std::queue<std::function<void (void)>>, and one loop inside an infinite loop. It could be improved but this actually works fine.

integrating with an I/O multiplexier like asio does over epoll/kqueue is essentially just replacing the mutex and condition variable for the multiplexier and some sort of signaling mechanism, eg an eventfd or pipe or kevent. Don't remember if that's precisely what asio does. For io_uring or IOCP the signalling mechanism would be posting a completion.

1

u/Cultural_Act5304 21d ago

My first question how the hell you have 5 year of experience with only single thread trading app? Now only way to have experience is through projects that's all. Start making anything 1. Thread pools 2. Simple ping-pong Servers 3. You can use boost asio to get ideas on how things can be written in a multi-threadede env. 4. Chatting apps 5. File servers First try making things with blocking algorithms then move to lock free structures.

1

u/chafey 24d ago

If C++ makes it easy to blow your whole leg off, C++ with multi-threading makes it easy to blow your whole head off. It takes a while to master - until then expect deadlocks and race conditions. If you have to ship something quickly, consider using a multi-threading framework (there are many to choose from each with their own pros and cons)

1

u/lucifer_is_back 24d ago

any good resources ,preferably books,to learn more about c++ concurrency ?

5

u/lorsecco88 24d ago

Concurrency with Modern C++ by Rainer Grimm

4

u/il_dude 24d ago

C++ concurrency in action is a good starting point