C ++ threads and concurrency
1. Ice thread model
The ice server is multi-threaded. The server run time maintains a thread pool for processing incoming requests. Through the leader-follower thread model, each operation call sent by the customer is distributed in its own thread.
Multithreading means that multiple calls from customers can be concurrently executed on the server. The ice thread Library provides many synchronization primitives, such as simple mutex, read/write locks, and monitors. These synchronization primitives allow concurrency control at different levels.
2. Thread library Overview
The ice thread Library provides several thread-related abstractions: mutex, recursive mutex, read/write recursive mutex, monitor, and a thread abstraction, allows developers to create, control, and destroy threads (the thread API is part of the iceutil namespace ).
3. mutex
Iceutil: mutex class (defined in iceutil/mutex. h) and iceutil: staticmutex (defined in iceutil/staticmutex. h) provide a simple non-recursive mutex mechanism:
namespace IceUtil { class Mutex { public: Mutex(); ~Mutex(); void lock() const; bool tryLock() const; void unlock() const; typedef LockT<Mutex> Lock; typedef TryLockT<Mutex> TryLock; }; struct StaticMutex { void lock() const; bool tryLock() const; void unlock() const; typedef LockT<StaticMutex> Lock; typedef TryLockT<StaticMutex> TryLock; };}
Suppose there is a file class named filesystem, which has a read and write operation function (for example, write ):
#include <IceUtil/Mutex.h>// ...namespace Filesystem {// ... class FileI : virtual public File,virtual public Filesystem::NodeI { public: // As before... private: Lines _lines; IceUtil::Mutex _fileMutex; };// ...}
Filesystem::Lines;
void Filesystem::FileI::write(const Filesystem::Lines & text,const Ice::Current &){ _lines = text; // Not thread safe!}
After the thread mechanism is added:
void Filesystem::FileI::write(const Filesystem::Lines & text,const Ice::Current &){ _fileMutex.lock(); _lines = text; _fileMutex.unlock();}
However, the use of such lock and unlock operations has a fixed problem: If the write unlock operation is missing in the program, or the program has returned before the unlock operation is completed, A deadlock occurs.
To unlock the mutex lock, the mutex class contains two types of helper classes: Lock and trylock:
namespace IceUtil { class Mutex { // ... typedef LockT<Mutex> Lock; typedef TryLockT<Mutex> TryLock; };}
Lockt and trylockt are simple templates, mainly composed of constructor and destructor;The constructor calls lock for its parameters, while the Destructor calls unlock.Rewrite the write function now:
void Filesystem::FileI::write(const Filesystem::Lines & text,const Ice::Current &){ IceUtil::Mutex::Lock lock(_fileMutex); _lines = text;}