第 18.19 節

Concurrent programming

0瀏覽次數0訪問次數--跳出率--平均停留

What problem does this section solve?

Modern computers typically have multiple CPU cores. If a program executes sequentially on a single thread, it cannot advance multiple time-consuming tasks simultaneously. Typical scenarios include:

  • One thread keeps the interface responsive, while another handles background tasks.
  • Wait for multiple network requests, timers, or peripheral events simultaneously.
  • Assign divisible computational tasks to multiple threads.

The challenges of concurrent programming lie not in "creating threads" itself, but in their lifecycle and shared data. Whenever two threads read and write to the same data simultaneously, synchronization issues must be carefully handled.

learning path

This section is divided into several file-level sub-sections for learning:

  • std::thread: create a thread, and use join() to wait for its completion.
  • std::mutex and std::lock_guard: Protect shared data.
  • std::atomic: Lock-free thread-safe operations for a simple counter.
  • std::condition_variable: One thread waits for another thread to send a notification.

If only one task is started, the results of synchronization and concurrency may appear identical. The differences typically become apparent only when "two or more tasks are waiting or computing simultaneously." This follows the same principle as with Boost.Asio, where the advantages of asynchronous operation aren't visible with a single timer—only when using two timers can you discern the difference.

C++ standard version

C++11 introduced the standard threading library. C++14, C++17, and C++20 added tools such as std::shared_mutex, std::jthread, std::latch, and std::barrier.

This section primarily uses basic tools available in C++11. Compilation typically requires adding thread options, such as:

g++ demo.cpp -std=c++17 -pthread

Common Tools

ToolseffectCommon Header Files
std::threadCreating and Managing Threads<thread>
std::this_thread::sleep_forThe current thread sleeps for a period of time.<thread><chrono>
std::mutexMutex, protecting shared data.<mutex>
std::lock_guardRAII locking, automatically released when its scope ends.<mutex>
std::unique_lockMore flexible RAII locks, often used with condition variables.<mutex>
std::atomicAtomic variables are suitable for simple counting.<atomic>
std::condition_variablewait and notify<condition_variable>

Concurrency and parallelism

conceptMeaningexample
concurrencyMultiple tasks are advanced within the same timeframe.A program simultaneously waits for network, timer, and user input.
parallelDo multiple tasks really run simultaneouslySimultaneous multi-threaded computation on multi-core CPUs

When starting out, first develop engineering intuition: when multiple tasks wait for peripherals, networks, timers, or time-consuming computations, let them advance simultaneously, and the program as a whole becomes faster or more responsive.

使用建议

  • 明确目标:在开始前确定您的具体需求,以便选择最合适的工具或教程。
  • 充分利用资源:参考官方文档、教程和博客,这些资料能帮助您快速上手并解决问题。
  • 实践应用:通过动手操作项目或编写代码来巩固学习成果,提升实际操作能力。
  • 问题解决:遇到困难时,查阅参考资料或寻求社区支持,逐步培养独立解决问题的能力。
  • 分享经验:完成项目后,可以撰写文章或博客分享心得,帮助其他学习者。

如果需要针对特定领域(如单片机、机器人或环境搭建)的进一步建议,请提供更多信息,我将为您细化内容。

  1. First ensure correctness, then consider performance.
  2. Avoid sharing data whenever possible, as each thread handling its own data is simplest.
  3. Prioritize using mutex for protecting shared data, and only consider atomic for simple counting.
  4. Keep the scope of locks as minimal as possible and avoid holding locks for extended periods.
  5. In the initial stage, avoid using detach() and prefer join() to explicitly wait for thread termination.
  6. In C++20 projects, you might look into std::jthread, which automatically requests a stop and joins on destruction, making it safer than std::thread.

Engineering expansion

In ROS2, multithreaded callback executors, callback groups, and shared state protection all involve threads and locks. In Boost.Asio, multiple asynchronous tasks may run in the same io_context or thread pool, and one must also consider shared data between callbacks. Mastering the concurrency tools in the C++ standard library makes it much easier to work with these engineering libraries.

音乐页