As already stated many times, data races are situations programmers try to avoid at all costs. In the previous chapter, we discussed a deadlock and ways to avoid it. The last example that we used in the previous chapter was making a thread-safe singleton pattern. Let's suppose we use a class for creating database connections (a classic example).
Here's a simple implementation of the pattern that tracks down the connections to the database. Keeping a separate connection each time we need access to the database is not a good practice. Instead, we reuse the existing connection for querying the database from different parts of the program:
namespace Db { class ConnectionManager { public: static std::shared_ptr<ConnectionManager> ...