Mutex and semaphores are the two foundations of multi-thread programming. I won’t go into details about their principles. Please read the operating system book or check online.
For the implementation of mutual exclusion, no matter what operating system, there are three steps that are inseparable
Initialize mutual exclusion lock
Lock operation
Unlock operation
For different systems, there are only some differences in the functions implemented, but the functions are actually similar. During lock operations and unlock operations, most systems have a timeout mechanism in them to ensure that they are not always locked in a certain state. In this place, for the sake of simplicity of the framework, we did not set a timeout. If we cannot get the lock during the lock operation, we will wait there forever.
We describe the base class of Mutex as follows
class CMutex { public: CMutex(const char *pName = NULL); //初始化锁 ~CMutex(); virtual bool Lock()=0; //锁操作,纯虚函数 virtual bool UnLock()=0; //解锁操作,纯虚函数 const char * getName(void) const { return mutex_name; } protected: char *mutex_name; //锁名字 };
For the implementation of each system, it is necessary to complete three parts: initialization, lock operation, and unlock operation. Under Linux, these three operations are very simple, so I won’t post the code here.
Similarly, for the semaphore Sem, the implementation of each system is similar, nothing more than
Initializing the semaphore
Sending the semaphore (semaphore +1)
Receive semaphore (Semaphore -1)
The Sem base class is described as follows
class CCountingSem { public: typedef enum { kTimeout, kForever }Mode; CCountingSem(); //初始化信号量 ~CCountingSem(); virtual bool Get() = 0; //接收信号量 virtual bool Post(void) = 0; //发送信号量 };
Similarly, I won’t post the code for the specific implementation.
Of course, for a system that satisfies the design pattern, when creating new mutexes and semaphores, of course you cannot directly new these classes, and you must return them through a simple project. , add newMutex and newCountingSem methods in the COperatingSystemFactory class, and return the corresponding entities through COperatingSystemFactory's judgment of the operating system.
class COperatingSystemFactory { public: static COperatingSystem *newOperatingSystem(); static CCountingSem *newCountingSem(unsigned int init=0); //参数是信号量的初始值,一般为0 static CMutex *newMutex(const char *pName=NULL); };
Okay, with the mutex and semaphore, how to use it? In the main function, we can apply for the mutex lock and semaphore first. If we Many threads are started. If a mutex lock is needed between some of them, then we assign the applied mutex lock to the corresponding thread, and then it can be used directly. As for each thread class, you wrote it yourself and just inherited it from CThread. It goes without saying how the member variables in it are related to the mutex lock applied for in main. You can also set it to public assignment. Set You can also use the function set from private, everything is up to you.
With the mutex lock and semaphore, the message queue can be started. With the message queue, the simplest multi-threading model is completed.
github address:
https://github.com/wyh267/Cplusplus_Thread_Lib
The above is the C++ multi-threading framework (2) : Mutex mutual exclusion and Sem semaphore content. For more related content, please pay attention to the PHP Chinese website (www.php.cn)!